Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Elegant way to dereference an array or hash?

by danb (Friar)
on Nov 16, 2004 at 19:27 UTC ( [id://408219]=perlquestion: print w/replies, xml ) Need Help??

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

Are there any elegant ways to dereference an array or hash besides @{} and %{}? In my opinion, the standard method gets ugly in cases like this:

@baz = @{ $foo->{ bar }->{ baz } };

I see the problem as the @ not being close enough to the variable that it is operating on. It's next to foo when it should be close to baz.

Many people work around the problem at the expense of some elegance:

$baz_ref = $foot->{ bar }->{ baz }; @baz = @$baz_ref;

Here is a fictional alternative that requires the baz array ref to be an object instead of a primitive array:

@baz = $foo->{ bar }->{ baz }->to_array();

Here is another fictional alternative that may conflict with existing valid syntax (and therefore would not be backwards compatible if implemented):

@baz = $foo->{ bar }->@{ baz };

(As a side note, is Perl 6 going to be different in this regard?)

-Dan

Replies are listed 'Best First'.
Re: Elegant way to dereference an array or hash?
by Arunbear (Prior) on Nov 16, 2004 at 19:50 UTC
    In Perl 6, that will become
    @baz = $foo{'bar'}{'baz'};
    or
    @baz = $foo<<bar>><<baz>>;
Re: Elegant way to dereference an array or hash?
by fglock (Vicar) on Nov 16, 2004 at 20:12 UTC

    You can drop one arrow:

    use strict; my @baz; my $baz = [ 1, 2, 3 ]; my $bar = { baz => $baz }; my $foo = { bar => $bar }; @baz = @{ $foo->{ bar }{ baz } }; print "@baz\n"; # 1 2 3
Re: Elegant way to dereference an array or hash?
by NetWallah (Canon) on Nov 16, 2004 at 21:24 UTC
    The methods above make COPIES of the array.

    It is possible (but not necessarily a good idea) to avoid that, using Typeglobs:

    my $foo = {bar=>{baz=> [3,4,5,6]}}; local *baz= $foo->{bar}{baz}; # typeglob ALIAS, not a copy print qq(@baz);
    The obscurity vs efficiency of this kind of code might be a worthwhile tradeoff if run frequently, and/or with large arrays, when used correctly, and documented.

        Earth first! (We'll rob the other planets later)

      I have worked on tons of legacy code that used typeglobs in this way, one thing I can suggest is a var prefix that is standardized across the codebase. It makes it a lot easier to trace things out if you are looking at $tgl_varname or some such vs $randomname when the typeglob alias is created half way across a large sub or file. Also IMHO the long form deref is better all around as it does not introduce one more var name to keep track of in my tiny head.


      -Waswas
Re: Elegant way to dereference an array or hash?
by ikegami (Patriarch) on Nov 16, 2004 at 19:52 UTC

    IIRC, Perl 6 will be @baz = $foo{bar}{baz};. In other words, it will automatically dereference when needed.

    In Perl 5, the most compact I can think of is @baz = @{$$foo{bar}{baz}};

Re: Elegant way to dereference an array or hash?
by Fletch (Bishop) on Nov 16, 2004 at 19:35 UTC

    I don't know that I'd say it's too far from what it's working on because you dereference a value, not a varaible. Whether it's in $foo or $foo->{bar}->{baz}->{quux} you're still dereferencing the same thing, a single reference. The difference in the two cases is where that value's coming from. I think the conventional wisdom is don't make your data structures deeper than they need to be, and use a temporary if it really bugs you (or if you're using something from way down the "tree" several times in the same scope).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://408219]
Approved by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-04-24 05:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found