Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am having problems constructing an array of hashes. I was trying to use this example - 1976 but I am doing something incorrectly. Here is some test code.
#!/usr/bin/perl use warnings; use strict; use LWP::Simple qw(); use LWP::UserAgent; use HTML::Treebuilder; use HTTP::Request; my $raw_html = LWP::Simple::get("http://www.perlmonks.org") || die + ("$!\n"); # print $raw_html; my $tree = HTML::TreeBuilder->new; $tree->parse($raw_html); $tree->eof; #$tree->dump; my @image_array=(); my %image = (); foreach my $image ($tree->look_down("_tag", "img")){ push (@image_array, \%image); } use Data::Dumper; print Dumper(@image_array);
This outputs:
$VAR1 = {}; $VAR2 = $VAR1; $VAR3 = $VAR1; $VAR4 = $VAR1;
If I modify the original code to this you can see it outputs an array for each image in the html:
#!/usr/bin/perl use warnings; use strict; use LWP::Simple qw(); use LWP::UserAgent; use HTML::Treebuilder; use HTTP::Request; my $raw_html = LWP::Simple::get("http://www.perlmonks.org") || die + ("$!\n"); # print $raw_html; my $tree = HTML::TreeBuilder->new; $tree->parse($raw_html); $tree->eof; #$tree->dump; my @image_array=(); my %image = (); foreach my $image ($tree->look_down("_tag", "img")){ print $image; }
This version outputs this:
HTML::Element=HASH(0x221d7b8)HTML::Element=HASH(0x2240b30)HTML::Elemen +t=HASH(0x2240be4)HTML::Element=HASH(0x22421e8)
I am trying to build an array of these hashes that I will be using later in my script. Thanks in advance for any help!!

Edited by Chady -- linked node id.

Replies are listed 'Best First'.
Re: problems constructing an array of hashes
by Zaxo (Archbishop) on May 13, 2004 at 17:07 UTC

    In your working example, you deal with the loop variable $image. The non-working example sets up the same variable, but pushes a reference to %image, which is not the same and is never populated. Change to push @image_array, $image; or, more simply, replace the whole loop with my @image_array = $tree->look_down("_tag", "img");

    After Compline,
    Zaxo

Re: problems constructing an array of hashes
by Enlil (Parson) on May 13, 2004 at 17:11 UTC
    I think if you change:
    use Data::Dumper; print Dumper(@image_array);
    to
    use Data::Dumper; print Dumper \@image_array;
    You will see the type of structure you are aiming for.

    On a seperate topic though since you are my %image outside the foreach block you will find that all the elements pushed onto @image_array will be a reference to the SAME hash. (also because just because $image is a hash_ref, apart from the similarities in the name it does not relate in any way to %image.)I doubt this is what you intend. From your second bit of code I would assume what you are looking for is something like:

    #!/usr/bin/perl use warnings; use strict; use LWP::Simple; use LWP::UserAgent; use HTML::Treebuilder; use HTTP::Request; use Data::Dumper; my $raw_html = LWP::Simple::get("http://www.perlmonks.org") || die("$!\n"); my $tree = HTML::TreeBuilder->new; $tree->parse($raw_html); $tree->eof; my @image_array; foreach my $image ($tree->look_down("_tag", "img")){ push @image_array, $image; } print Dumper \@image_array;

    update: Zaxo's solution above nicely skips the accomplishes the same population of the @image_array without the foreach loop.

    -enlil

      Thanks all! Here is what I am using now. Works like a champ :)
      #!/usr/bin/perl use warnings; use strict; use LWP::Simple qw(); use LWP::UserAgent; use HTML::Treebuilder; use HTTP::Request; use Data::Dumper; my $raw_html = LWP::Simple::get("http://www.perlmonks.org") || die + ("$!\n"); # print $raw_html; my $tree = HTML::TreeBuilder->new; $tree->parse($raw_html); $tree->eof; #$tree->dump; my @image_array = ($tree->look_down("_tag", "img")); foreach my $img (@image_array){ print "image src $img->{'src'}\n"; print "image width $img->{'width'}\n"; }