Nick Chettle <mailto:[EMAIL PROTECTED]> wrote:
: I am not 100% sure what this line does.
:
: push @{ $msgids->{$1} }, $_;
:
: Is the @{} surrounding the hash used to make push work with a hash?
No. We cannot push items onto a hash. We need an array for
that. "$msgids->{$1}" is an array reference. It refers to an
array reference inside a hash which is, in turn, referenced by
a hash reference ("$msgids").
"$msgids->{$1}" is an array reference. The "@{}" allows us
to de-reference the reference. As you may recall, an array is a
list of items.
my @animals = ( 'cat', 'dog' );
Sometimes it is more convenient to use a scalar variable than
an array variable.
my $animals_ref = [EMAIL PROTECTED];
In fact, we don't really need the original array. We can create
the reference and operate on just it. We use "[]" to define an array
without a name.
my $animals_ref = [ 'cat', 'dog' ];
To add an item to the end of an array, we use "push".
my @animals = ( 'cat', 'dog' );
push @animals, 'horse';
my $animals_ref = [ 'cat', 'dog' ];
push @{ $animals_ref }, 'horse';
We could have pushed everything onto the array.
my @animals;
push @animals, 'cat';
push @animals, 'dog';
push @animals, 'horse';
my $animals_ref;
push @{ $animals_ref }, 'cat';
push @{ $animals_ref }, 'dog';
push @{ $animals_ref }, 'horse';
my $msgids;
push @{ $msgids->{Fred} }, 1005;
push @{ $msgids->{Fred} }, 1058;
push @{ $msgids->{Fred} }, 2587;
In the example above, there exists a reference to a hash named
"$msgids". Autovivification allows the hash to add keys when a new
one is used. So, if $1 is a new key it will be added to the hash,
otherwise we will use an existing key.
Since $msgids is a reference hash of arrays. But hashes can
only contain scalar values, you say. No problem, the arrays we
store in the hash are actually array references.
So technically, $msgids is a reference to a hash of array
references. Pretty complicated, huh? Read perlref for an intro
to perl data structures.
: Also, why do you need ->
Because the author chose to use a hash reference to a hash.
my $msgids;
while (<MAILLOG>) {
if (/$email/) {
if (/([A-Z1-9]{8})/) {
push @{ $msgids->{$1} }, $_;
}
}
}
: and can't just do $msgids{$1}, $_; ?
my %msgids;
while (<MAILLOG>) {
if (/$email/) {
if (/([A-Z1-9]{8})/) {
push @{ $msgids{$1} }, $_;
}
}
}
: I made a slight change to make your addition work in that I added ()
: around the regex so that $1 would work - is there any reason to use
: this over $&?
:
: So, AFAICS, your addition creates a hash (Using the message id's as
: the key) and puts the associated line from the log in the hash. So I
: thought I could simply do:
:
: for (sort keys %msgids) {
: print $msgids{$_};
: }
:
: To print each line found. For some reason this returns nothing.
You didn't turn on strict or warnings. There is no %msgids.
You would get all sorts of warnings otherwise. This should work.
#!/usr/bin/perl
use strict;
use warnings;
print "Please enter an e-mail address: ";
chomp( my $email = <STDIN> );
my $file = '/var/log/maillog';
open MAILLOG, $file or die qq(Cannot open "$file": $!);
my %msgids;
while (<MAILLOG>) {
if (/$email/) {
if (/([A-Z1-9]{8})/) {
push @{ $msgids->{$1} }, $_;
}
}
}
close MAILLOG;
foreach my $key (sort keys %{ $msgids } ) {
print $msgids->{ $key };
}
__END__
OR:
#!/usr/bin/perl
use strict;
use warnings;
print "Please enter an e-mail address: ";
chomp( my $email = <STDIN> );
my $file = '/var/log/maillog';
open MAILLOG, $file or die qq(Cannot open "$file": $!);
my %msgids;
while (<MAILLOG>) {
if (/$email/) {
if (/([A-Z1-9]{8})/) {
push @{ $msgids{$1} }, $_;
}
}
}
close MAILLOG;
foreach my $key (sort keys %msgids) {
print $msgids{ $key };
}
__END__
HTH,
Charles K. Clarkson
--
Mobile Homes Specialist
254 968-8328
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>