From: john@sekrit.WPI.EDU (John Stoffel)
Newsgroups: comp.lang.perl
Subject: Question on use of Next, Redo and Last
Date: 14 Sep 92 17:34:43
Organization: Worcester Polytechnic Institute
Distribution: world
NNTP-Posting-Host: sekrit.wpi.edu


I've been writing a program to parse through a bunch of mail messages
consisting of syserr logs from workstations that we manage on campus
here.  I used some code written by Larry Wall to parse out the machine
the error log came from and some other info, and then the body of the
message which contained the actuall log for that day.  I still don't
totally grok (or even understand!  :-) why the code works.  I've read
the camel book quite a few times, but the section on last, next, etc
is kinda weak without a really good contrived example.  Here is
Larry's code and then mine, just to give an example I can deal with. 

Thanks!

					John

----------------------------larry code---------------------------------

# Taken from his reply to dana@thumper.bellcore.com

$USER = $ENV{'USER'};
open(MAILBOX, "/usr/spool/mail/$USER")
    || die "cannot open mailbox for $USER: $!\n";

$/ = "";

while (<MAILBOX>) {
    next unless /^From /;
    next unless /\*\*Phone Message\*\*/;

    # Got one...

    $_ = <MAILBOX>;	# Assuming next paragraph contains this stuff:
    ($from) = /From:  +(.*)/;
    ($comp) = /Company: +(.*)/;
    ($phone) = /Phone: +(.*)/;
    print "F: $from ($phone). M: ";

    while (<MAILBOX>) {
	last if /^From /;
	tr/\n/ /;		# or maybe tr/\n/ /s
	print;
    }
    print "\n";
    redo if $_;			# moral equivalent of unget
}


-----------------------my code-------------------------------------
#!/usr/local/bin/perl
#
# 
# This program reads in a bunch of mail messages from the syserr demons and 
# creates a summary report.  This saves my brain cells and fingers!
# 
# fmterr.pl version 1.0  9/10/92
#

$syserr = "/usr1/john/.SYSERR";

$/ = "";	# to read in paragraphs of stuff
		# tried using "From ", but that just caught
		# the beginning headers AFTER they went through.
		# maybe redo would do the trick?

$\ = "\n";

open(SYSERR,$syserr) || die "Can't open $syserr: $!\n";

TOP:
while (<SYSERR>) {
    next unless /^From /;

    ($hostname) = join('',"--",/Subject: syserr on (\w+)\.*/,"--");
    ($date) = /Date: .*, (.*) \d\d.*/; 
    ($num) = split(' ',$date,1);
    if ($num < 10) {
	$date = '0' . $date;
    }
    $host{$hostname . $date} = $hostname;  # I like being able to do this!
    $date{$hostname . $date} = $date;

    while (<SYSERR>) {
	last if /^From /;

	$tmp = $tmp . $_;
    }				
    
    $data{$hostname . $date} = $tmp;
    undef($tmp);

    redo if $_;
}				 

$~ = BODY;

foreach $key (sort keys %host) {
    split(/^/,$data{$key});
    undef($count);
    undef($tmp);
    foreach (@_) {
	if (/file: table is full/) {
	    $count++;
	}
	else {
	    $tmp = $tmp . $_;
	}
    }
    if (defined($count)) {
	$tmp = $tmp . " file: table was full $count times\n\n";
    }

    undef($data{$key});
    $data{$key} = $tmp;
    write;
}

format BODY =
---------------------------------------------------------------------------
@<<<<<<<<<<<<<<<                                              --@<<<<<<<<--
$host{$key},$date{$key}

@*
$data{$key}
.






--
Youth of today!  Join me in a mass rally for traditional mental attitudes!
-------------------------------------------------------------------------------
john@wpi.wpi.edu | Work Station Specialist | Worcester Polytechnic Institute
John Stoffel     | 508-831-5512 (work)     | Worcester, MA  01609