http://qs321.pair.com?node_id=426636

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

Hello Monks

I am having some difficulty parsing back out the data contained in a hash reference. I am looking to print the data that I have passed in the reference. I can do it with Dumper but that's it.

I would REALLY like a pointer to the perl books on where this is covered. I need to bookmark it.

use strict; use Data::Dumper; my $names = &getNames; my $valid_names = &validateNames(\$names); sub getNames { my %data; $data{'SCM555'}{'name'}='foo'; $data{'SCM555'}{'email'}='foo@bar.com'; $data{'SCM556'}{'name'}='foo2'; $data{'SCM556'}{'email'}='foo2@bary.com'; return \%data; } sub validateNames{ my $valid_names=shift; print Dumper($valid_names); # I want to access ( print ) the data here }


TIA


Rhodium

The seeker of perl wisdom.

Replies are listed 'Best First'.
Re: Passing hash references
by borisz (Canon) on Jan 31, 2005 at 16:07 UTC
    Since $names is already a hashref, there is no need to reference the reference again. Please change
    my $valid_names = &validateNames(\$names);
    to
    my $valid_names = &validateNames($names);
    in your sub validateNames you can access the hashref with the -> operator.
    sub validateNames{ my $valid_names=shift; print $valid_names->{SCM555}->{email}; print $valid_names->{SCM556}->{name}; }
    Boris

      Boris,

      Just to be consistant with the original poster's code style, whether that's the way you do it or not (it happens to be the way I do things, but it seems I'm in the minority ;->), the arrow operator after a close-brace is not required:

      print $valid_names->{SCM555}{email};
      Rhodium - note, too, that the quotes inside the braces are optional. I prefer without the quotes (unless required - which they are for certain things), but I do recommend consistancy, even if you disagree with other aspects of my coding style ;-)
      print $valid_names->{'SCM555'}{'email'};

Re: Passing hash references
by olivierp (Hermit) on Jan 31, 2005 at 16:21 UTC
Re: Passing hash references
by edoc (Chaplain) on Jan 31, 2005 at 16:14 UTC

    I'll hazard a guess that your confusion stems from a single extra character in your code..

    my $valid_names = &validateNames(\$names);

    You don't need the '\' before names. It's already a reference as returned by getNames, so you're actually sending a reference-to-a-reference to your function. Change it to:

    my $valid_names = &validateNames($names); # or even my $valid_names = validateNames($names);

    and you'll be able to access the values in your validateNames function with:

    print $valid_names->{SCM555}{name};

    cheers,

    J

Re: Passing hash references
by bgreenlee (Friar) on Jan 31, 2005 at 16:16 UTC

    One issue you have is that you're adding a level of indirection by passing a reference to $names to validateNames, but it's already a reference (to the %data hash). So just call &validateNames($names).

    As for printing the data, you can do this:

    for my $key (keys %$valid_names) { print "key: $key\n"; print " name: $valid_names->{$key}{name}\n"; print " email: $valid_names->{$key}{email}\n"; }

    Finally, the places to look for more information on data structures and references are: perldata, perldsc, and perlref.

    -b

Re: Passing hash references
by fauria (Deacon) on Jan 31, 2005 at 16:24 UTC
    In general, i access hashrefs values which i dont know their structure by looking at Data::Dumper output, and then:

    $hashref->{brackets_1}->{brackets_n}{quotes}

    Regarding books, i really like Perl Cookbook, chapter 5 covers this topic.

    Also, ive found Merlyn's article List Manipulation, very useful. It was published in April 2004 Linux Magazine issue.

    Finaly, you can take a look at Steve's place lesson 7. It is really good.
      my $names = &getNames; my $valid_names = &validateNames(\$names); usually, I noticed that &validateNames(\$names); could be &validateNames($names); just to make things easier. However, you can use it, just more messy looking
      sub validateNames{ my $valid_names=shift; print Dumper($valid_names); # I want to access ( print ) the data here my $category = (); foreach $category (sort keys %{${$valid_names}}) { print "INFO - $category . Name : " . ${${$valid_names}}{$category +}{'name'} . "\n"; print "INFO - $category . Email : " . ${${$valid_names}}{$catego +ry}{'email'} . "\n"; } }