Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

%h->{foo} vs. $h{foo}..

by smferris (Beadle)
on May 30, 2003 at 04:49 UTC ( [id://261763]=perlmeditation: print w/replies, xml ) Need Help??

First an apology if this doesn't fit this discussion area

In a node I started about tie and DBI giving me trouble, I apparently made a mistake by saying that I thought %h->{foo} was syntatically clearer than $h{a} and was immediately corrected in this node that it was being deprecated and no experienced perl coder would aggree with me.

Naturally, I have to question that.. $h->{foo} is clearly dereferencing the value of foo in a hashref.. %h->{foo} is clearly dereferencing the value of foo in a hash.

$h{foo} just seems like the exception to the rule if the rules are $=scalar/ref, %=hash, @=list. (clear and concise) Grant it, I believe hashes (and lists) are implemented as refs behind the scene and in that sense it makes sense.. It just looks weird to me. Again.. My opinion.

Now.. %h{foo} would be clearer yet.. But I take offense to the statement that experienced perl coders wouldn't use it.. possibly implying that I'm not experienced.. Grant it, I'm no saint.. but I'm no slouch either. Can I be that wrong if %h{foo} is introduced in perl6: Exegesis 2 At least someone thinks it could be written clearer.

I'm not trying to start a flame war here, but I am curious as to why people think %h->{foo}/$h->{foo} is less clear than $h{foo}/$h->{foo}.

What's your opinion? 8)

Replies are listed 'Best First'.
Re: %h->{foo} vs. $h{foo}..
by BrowserUk (Patriarch) on May 30, 2003 at 06:18 UTC

    My take on it goes like this

    my %foo; is obviously a hash.

    my $foo = \%foo; is a scalar that 'points' to the hash %foo.

    x->{fred} says, x is a scalar that points to a hash, and I want to use the element of that hash that has the key 'fred'.

    The problem with %h->{fred} is that it implies that %h is a reference, but references are stored in scalars.

    %h = (fred=>'bloggs', bill=>'stickers'); $href = \%h; print %h; # Gives fredbloggsbillstickers print $href; # Gives HASH(0xibc2d18)

    So, the syntax %h->{fred} essentially is saying that %h is "the hash", but also that %h "points to the hash" which boils down to


    which doesn't make a lot of sense. The fact that it ever worked was a mistake. If you try this in 5.8 you get

    Using a hash as a reference is deprecated at...

    And whilst $hash{fred} will be written as  %hash{fred} in P6, I don't believe that %hash->{fred} will be legal.

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller

Re: %h->{foo} vs. $h{foo}..
by perrin (Chancellor) on May 30, 2003 at 05:24 UTC
    %h->{foo} looks immediately and obviously wrong to me. I've never seen any docoumentation or example do that. In fact, anything with a % or @ and an arrow following it looks wrong. The arrow always dereferences or calls a method on a ref, and a ref always looks like $something.

    $h{foo} is not an execption to the rule. The $ refers to the scalar you want back, just as it does with an array when you say $array[0].

Re: %h->{foo} vs. $h{foo}..
by Juerd (Abbot) on May 30, 2003 at 09:59 UTC

    %foo is a hash, @foo{@keys} is a hash slice and $foo{key} is a hash element. It has nothing to do with @foo and $foo at this point (except that if they are global, they share a glob).

    \%foo is a reference to the same hash which can be assigned to $foo. Then, $foo->{key} is that element again.

    %foo->{key} is wrong. -> should only be used with references and classes. To either call a method on the reference if its referent is blessed (or the LHS is a class), or to access an element in the refered hash or array. %foo is not a reference, so the arrow should not be used with it.

    Perl 6 will no longer use sigils to indicate how the variable is used. In Perl 5, we use a different sigil if we use the hash differently. That is: % to get the entire hash, @ to get a slice and $ to get a single element. In Perl 6, we use % for hashes, % for hashes and %for hashes. That meas %foo{key} will be valid.

    Your %foo->{key} relies on a bug in Perl 5. The same, translated to Perl 6 would be %foo.{key}, which would rely on a feature in Perl 6. That feature is automatic referencing, so that what you wrote is in fact (\%foo).{key}.

    %foo->{key} is unclear because no experienced Perl coder is used to seeing the arrow operator with something that is not a reference or a class. What about unexperienced Perl coders then? Well, they don't understand what it means, try to find out and find that it is not documented. They will take for granted that it works, probably not knowing that you really meant $foo{key}.

    Juerd # { site => '', plp_site => '', do_not_use => 'spamtrap' }

Re: %h->{foo} vs. $h{foo}..
by diotalevi (Canon) on May 30, 2003 at 04:52 UTC

    Actually I'd take all usages of -> to mean a reference was being dereferenced. The leading sigil would be nice to keep the same - %h->{foo} vs $h->{foo} though. It turns out perl6 is doing something like that though I forget the actual syntax.

Re: %h->{foo} vs. $h{foo}..
by smferris (Beadle) on May 30, 2003 at 05:59 UTC

    Documented or not, it was implemented.. So, I guess, that's two people that didn't think it was totally unreasonable. I'm also guessing that person was an experienced perl coder that implemented it.. Their patch WAS accepted afterall. ;D (For quite awhile I might add.. 5.005 through 5.6.1, at least)

    Anyway.. You both make good points.. I'm to focussed on whats to the left of the arrow, where I should be focussing on the arrow itself. In that case, it makes perfect sense why it's wrong.

    Good thing I just stumbled on this, feature!? 8D I haven't used it much. Thanks for the discussion!

      Documented or not, it was implemented.
      No, this is an unfair statement. There was no extra code added to make it work. Instead, there wasn't enough code to make sure it was rejected as illegal.

      As others have pointed out, this code to make sure it's rejected as illegal is being slowly introduced into the implementation, so as not to break anyone's code that took advantage of this bug in the existing implementation.

      Amongst the developers, there is no controversy that @array->[$element] and %hash->{$element} has always been a bug.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        Sorry.. Not trying to beat a dead horse here.. But I don't think it's fair to call it a bug either.. not if something similar is being implemented in Perl6. %foo.{key} is different from %foo->{key}? Both let you access a hash as a hashref, rather than as a hash. (I'm assuming this is the source of my confusion. something I don't know about the Perl6 implementation, perhaps?)

        Un-Intentional, perhaps.. but a bug? Of course, I've never looked at more than a few lines of the source.. so I'm no-one to argue. 8) and please don't take it as such.. I really am just trying to see the big picture here.

        I love Perl and being bashed for something stupid I've done only makes me better.. right? ;D (provided I learn from it, of course) But.. Just to clear my point of view a little further: (Bare with me, this is long, I apologize)

        For instance, take a 1000 new Perl coders.. Explain that $ represents a scalar, and % represents a hash structure.. (Incomplete, I will not disagree.. but still a true statement) Now give them the code:

        1> $foo='bar'; 2> $foo{'bar'}='baz!'; 3> %foo=('calvin','hobbes');

        Ask them what foo represents on each line. (a hash or scalar) For the experienced perl coder, no problem. For the unexperienced, I'll bet the number of wrong answers isn't zero. (Line 2 being the one likely confused of course) Now give them the code:

        1> $foo='bar'; 2> %foo->{'bar'}='baz!'; 3> %foo=('calvin','hobbes');

        Ask again.. I'll bet their accuracy is a bit better.. My opinion is, the unexperienced perl coder could probably go their whole life w/o knowing about, or at least understanding refs and still write code that worked for them. Perfect example... back in the Perl 4 days.. A collegue of mine showed ME what a hash was.. Some 7-8 years later, I find myself trying to explain a hashref to them because they're trying to copy a hash (HOH) with $a{1}=$b{1} and they can't figure out why they can't modify $b{1} w/o affecting $a{1}.. But yet.. It's taken them almost 8 years to discover it. 8) (And I know they're still confused by them) I know they've used modules before and have had to instantiate them, so, indirectly they knew about 'em.. They were just unaware of them.

        As for the experienced, it may not look right, but I'll bet the number of wrong answers is closer to 0.. or at least much closer than the newb people with the initial code.

        Heck, Exegesis 2 is the reason I even tried %foo->{blah} to begin with.. I thought, Hmmm, what if that was available now, in 5.6.1? Let's try it.. Get used to using it.. and, Wow.. whataya know. it worked!

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://261763]
Approved by hossman
Front-paged by krisahoch
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-05-30 18:32 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.