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

I am only just beginning to get refs, despite having read Camel on the subject and many posts here. Actually, I am not even getting them, I am cargo_cult programming ("Hmm this worked before let's try it again").
The problem:
I can populate cells with Tr (\@cells) where @cells is:
@rows = map {$q->td( {-align=>'left'}, b("$_ Parish:") ). $q->td( {-bgcolor=>"$data"},@{$info{$_}}[$index]). $q->td( {-bgcolor=>"$data"},@{$info{$_}}[$index2]). $q->td( {-bgcolor=>"$data"},@{$info{$_}}[$index3]) } @ +keys;
What I want to do is migrate to including the Tr() method call in the map so I can print say @rows and have it do a Tr per %key for instance. Or maybe even a whole table, whatever, you get it. Thing is I got errors for an undeclared hash when I tried this and simply changing my code to say %cells where it had @cells did not work because ??? I can't just print \%cells ??? .
My question: How do I migrate from this arrayref to a hash ref? Or, alternately what is it that I fail to grok about this (as my question may be irrelevant to my problem)?
TIA
jg
_____________________________________________________
Think a race on a horse on a ball with a fish! TG

Replies are listed 'Best First'.
Re: From arrayref to hashref
by broquaint (Abbot) on Mar 21, 2002 at 15:08 UTC
    > Thing is I got errors for an undeclared hash when I tried this and simply changing my code to say %cells where it had @cells did not work because ???
    This is because %cells and @cells are 2 different entries in the symbol table, so they may have the same name, but they aren't the same variable.
    To assign to the hash %cells you could just say
    my %cells = map { ... };
    This works assuming that you'll be giving it a list with key-value pairs like so
    my %cells = qw(key1 val1 key2 val2 key3 val3);
    This is because hashes are assigned lists where each value alternates between being a key and a value. So the following are equivalent.
    my %cells = qw(foo one bar two baz three); my %cells = (foo => "one", bar => "two", baz => "three");

    HTH

    broquaint

Re: From arrayref to hashref
by erikharrison (Deacon) on Mar 21, 2002 at 15:56 UTC

    An addendum to broquaint for ref newbies:

    One thing that got me about array/hash refs is that I can assign an array to a hash, even elements becoming keys, odd elements becoming values:

    @array = (Bannana, Fruit, Corn, Vegetable); %hash = @array;# (Bannana => Fruit, Corn => Vegetable);

    But you cannot dereference an array ref to a hash:

    $food = \@array; print $$food{Corn}; # woops!

    Once I realized how it worked, I thought that I was stupid to have suspected otherwise - until I learned it was a semi - common problem.

    Hope that helps!

    Cheers,
    Erik

      Actually, it is not stupid -- you can use overload to make that kind of thing work (even without using bless(), I think, though I should have to tinker with it some).

      However, if you don't need to optimize for speed, and don't feel like tinkering with overload, there is always good old TIMTOWTDI:

      $food = \@array; print +{@$food}->{Corn}; # yay! print @{{@$food}}{Corn,Bannana}; # slice!

      Have the appropriate amount of fun with it :-)

      Update: Found a better CPAN search link.

      The Sidhekin
      print "Just another Perl ${\(trickster and hacker)},"

        Neato - Bandito! I hadn't even *thought* of that (You can tell I'm not much beyond newbie myself - at least I understood why it works). Thanks a bunch!

        Cheers,
        Erik
Re: From arrayref to hashref
by TGI (Parson) on Mar 21, 2002 at 22:08 UTC

    I'm not answering your question, sorry; but I do have a comment. One of my friends had the hardest time getting refs down, until she read thedamian's oft referenced book on OO programming with Perl.

    Besides, it looks like you've already got a good answer. There's a great chapter about overloading in the book, too.


    TGI says moo