Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

RE: RE: RE: RE: Re: Populating a Hash: Can someone help me to understand?

by Limo (Scribe)
on Sep 19, 2000 at 19:49 UTC ( #33107=note: print w/replies, xml ) Need Help??

in reply to RE: RE: RE: Re: Populating a Hash: Can someone help me to understand?
in thread Populating a Hash: Can someone help me to understand?

Well, I AM trying to create a hash with multiple values per key! Apparently, this is possible. I'm referring to "Perl Cookbook", pg. 140. There is an example of this, but I'm having a hard time understanding it.
  • Comment on RE: RE: RE: RE: Re: Populating a Hash: Can someone help me to understand?

Replies are listed 'Best First'.
(Guildenstern) REx6: Populating a Hash: Can someone help me to understand?
by Guildenstern (Deacon) on Sep 19, 2000 at 20:40 UTC
    Okay. I think I see what you're trying to do now. Based on what I see in the Cookbook on p 140, it looks like you want a hash whose values are array refs. This will effectively get you the "more than one value per hash key" that you're looking for. It is kind of hard to tell what to help you with regarding that particular example without a little smaller target for us to aim for.
    The example is fairly simple, except for the fact that instead of assigning values to an array, then setting the array reference to a hash key, it pushes values directly into the hash.
    BTW: here is the code I'm referring to:
    %ttys = (); open(WHO,"who|") or die "can't open who: $!"; while (<WHO>) { ($user, $tty) = split; push( @{$ttys{$user}}, $tty); } foreach $user (sort keys %ttys) { print "$user: @{$ttys{$user}}\n"; }

    The one line that looks like it might cause understanding problems is push( @{$ttys{$user}}, $tty); Basically, push expects a list for its forst argument, but $ttys{$user} will return a list refernce, not a list. Using @{...} forces push to evaluate what's in those braces as a list, which it knows how to work with.

    Negaterd character class uber alles!

      I find that removing the autovivication can make the code easier to understand (and I wish there was a way to force this):

      my %ttys= (); open( WHO, "who|" ) or die "Can't fork to read from who: $!"; while( <WHO> ) { my( $user, $tty )= split; if( ! exists $ttys{$user} ) { $ttys{$user}= [$tty]; } else { push @{$ttys{$user}}, $tty; } } foreach my $user ( sort keys %ttys ) { print "$user: @{$ttys{$user}}\n"; }

      The if shows a bit of what happens under the covers in the previous example.

              - tye (but my friends call me "Tye")
        I whole heartedly agree, but that code was taken verbatim from the Perl Cookbook, so it's easy to see how someone with little to no experience using references could be confused by that code. About the time you get a handle on \@, somebody throws @{...} at you? Ack!
        Also, I understand that the book's just full of examples, but shouldn't they at least make an effort to at least pass strict?

        Negaterd character class uber alles!
RE: RE: RE: RE: RE: Re: Populating a Hash: Can someone help me to understand?
by merlyn (Sage) on Sep 19, 2000 at 19:50 UTC
      That's what I was asking in my original post,"I've read about references from several sources; I think referencing the arrays are my answer, but I'm just not getting it."
        If you look at something and are confused, try to work out what it is saying. Take some guesses and experiment a few times. But basic concepts (like references) are not something someone can hand you on a platter. They can show you working code examples, but until you "get it" you will not figure out how it works. And if you first response to confusion is to ask another question then you are unlikely to ever learn how it works.

        I am sorry if this sounds harsh, it isn't meant to be. Some things just don't come easily.

        A reference is just a special kind of value that "points at" another Perl data structure. Nothing more, nothing less. A value of a hash has to be a single value. But that value can tell you where an array is that contains a whole list of arrays. You can now do the same things that you could do with a list of values, but you have to remember to always work with one level of indirection (called dereferencing) to get at the list.

        If that doesn't make sense then please do not ask a question about it. Instead go back to the code example you did not understand and look for the dereferencing. If you don't see it then read the explanations given there and other places for how you can create and destroy the reference. Play with it. Experiment with it.

        Enlightenment won't all come at once, but develop the habit of first digging into your own mental resources, then asking questions, and you will both learn faster and ask more productive questions.

        This is called "learning to learn" and the best way to learn that is go to work right now and figure out this concept for yourself, because nobody can hand you comprehension on a silver platter, it just does not work that way.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://33107]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (7)
As of 2020-05-26 23:36 GMT
Find Nodes?
    Voting Booth?
    If programming languages were movie genres, Perl would be:

    Results (152 votes). Check out past polls.