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

When is a hashreference a subexpresion?

by gam3 (Curate)
on Aug 09, 2006 at 01:49 UTC ( #566302=perlquestion: print w/replies, xml ) Need Help??
gam3 has asked for the wisdom of the Perl Monks concerning the following question:

I was wondering if someone would be kind enough to explain the following to me:
sub x { ('a', 'b', 'c', 'd'); } sub a { { x }; } sub b { $x = { c }; } sub c { { 'a', 'b', 'c', 'd' }; } sub d { { ('a', 'b', 'c', 'd') }; } print a, "\n"; print b, "\n"; print c, "\n"; print d, "\n";
subroutine 'a' returns a list, where subroutine 'b' returns a hash reference. It seems to me that they should both return a hash reference. I noticed this behavior when I had code that stated out as
{ a => 'b', c(), }
and then removed the a => 'b'. This caused code to break as the sub routine started returning a list instead of a hash reference.
-- gam3
A picture is worth a thousand words, but takes 200K.

Replies are listed 'Best First'.
Re: When in a hashreference a subexpresion?
by GrandFather (Sage) on Aug 09, 2006 at 02:31 UTC

    strictures would help pick up at least some of the problems you are having here.

    Using an explicit return would help not only Perl figure out what you are doing, but may help other people (you in 6 months even) figure out what the intended behaviour of the code is.

    {} can enclose a block or be a hash reference. Sometimes it's hard to tell which is intended. Perl is a good sport and will take a punt. Sometimes it fails to read your mind. Consider:

    use warnings; use strict; sub x { ('a', 'b', 'c', 'd'); } sub a { { x }; } sub g { return { x }; } print a, "\n"; print g, "\n";


    abcd HASH(0x182f30c)

    DWIM is Perl's answer to Gödel
Re: When in a hashreference a subexpresion?
by rodion (Chaplain) on Aug 09, 2006 at 02:15 UTC
    sub a { {x}; }

    The "{x}" is ambiguous. Are the curlies defining a hash reference, or are they defining a block. In this case it looks like a block, so that's what perl defines. More explicitly

    sub e { {x;} } sub f { {x => 1 } }

    Defines subs with a block and a hash ref respectively. Perl does a lot to figure out what you might mean when it's ambiguous, and mostly Perl gets it right. The more you help it, the better chance it has of understanding what you meant.

    Update: As usual, grandfather comes up with the best advice (see below); use an explicit "return".

Re: When in a hashreference a subexpresion?
by gcalexander (Novice) on Aug 09, 2006 at 04:12 UTC
    From what I can see, the use of curly braces in ambiguous. I.e. it can mean the start of a block, or a hash reference.

    The interpreter will try its hardest depending on the context to guess what you mean, but in this instance you have to provide a hint to the interpreter to disambiguate the brace.

    sub a { +{ x } }
    sub a { return { x } }
    should do the trick. I forgot which perl doc I read this in. It think it was perlref, but I'm not sure.
      +{ x } is forcing scalar context (scalar { x };).
        Yeah, that's right. Sure it does.. Uh-huh.

        I was going to write 'perhaps you should have thought about that before you wrote it', but I imagine you did and still got it completely wrong.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://566302]
Approved by GrandFather
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2017-02-21 20:35 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (319 votes). Check out past polls.