Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: Preventing unintended list expansion inside hash literals.

by kcott (Archbishop)
on Jan 05, 2017 at 09:38 UTC ( [id://1179000]=note: print w/replies, xml ) Need Help??


in reply to Preventing unintended list expansion inside hash literals.

G'day gregory-nisbet,

"What's the idiomatic way to guard against unintentionally expanding a non-singleton list into the bodies of your hashes?"

I don't know if there's an idiom for that specific case; however, as a general case, you can use scalar to force scalar context. So, if you're happy to have undef values in your hash:

key1 => scalar(some_key($bar))

If you don't want undef values and are using perl v5.10, or higher, you can do something like these:

key1 => (some_key($bar) // 0) key1 => (some_key($bar) // [])

If none of those suit, then what you're currently doing ("use an intermediate scalar variable") seems like a perfectly fine solution.

— Ken

Replies are listed 'Best First'.
Re^2: Preventing unintended list expansion inside hash literals.
by Athanasius (Archbishop) on Jan 05, 2017 at 09:55 UTC

    Hello kcott,

    I considered using scalar too, but then the comma operator returns the right-most value in the list, which doesn’t seem to be what the OP is looking for:

    19:53 >perl -MData::Dump -wE "sub f { return (17, 42); } my %h = ( key +1 => scalar f() ); dd \%h;" { key1 => 42 } 19:54 >

    Cheers,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      I was working on this from the OP:

      "However, when the hash table is empty, we just call return."

      That appears to be confirmed in his code example:

      ... %$hash_ref or return; # just return ... $key; # or last line in sub returns a scalar

      So, %some_hash is ending up as one of:

      ( key1 => ($val1), key2 => ($val2) ) ( key1 => (), key2 => () ) ( key1 => ($val1), key2 => () ) ( key1 => (), key2 => ($val2) )

      These will be flattened to:

      ( 'key1', $val1, 'key2', $val2 ) ( 'key1', 'key2' ) ( 'key1', $val1, 'key2' ) ( 'key1', 'key2', $val2 )

      The first is fine; the second is what the OP had a problem with; the last two are problematic but, assuming he's using warnings, should generate an "Odd number of elements in hash assignment" diagnostic (from perldiag).

      I don't think the "comma operator returns the right-most value in the list" comes into play in any of these scenarios: all lists are either empty or only have one value.

      Am I missing something with your "return (17, 42);" example?

      — Ken

        Hello Ken,

        No, you’re right: in the context of the OP’s example code, scalar works fine. I was looking to the more general question:

        What's the idiomatic way to guard against unintentionally expanding a non-singleton list into the bodies of your hashes?

        A “non-singleton list” can be an empty list (as in the example code), OR a list with more than one element. Use of scalar for the latter case returns the last element of the list, not the first. From the OP’s use of $array_ref->[0] as his example of “a single-element list,” I assumed that in this case he would want the first element of the list. But admittedly this is little more than a guess. :-( Sorry for the confusion.

        Cheers,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Log In?
Username:
Password:

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

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

    No recent polls found