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>


Reply via email to