Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: grep for hash?

by Fletch (Bishop)
on Jul 07, 2009 at 12:49 UTC ( [id://777866]=note: print w/replies, xml ) Need Help??


in reply to grep for hash?

TMTOWTDI . . .

use YAML::Syck qw( Dump ); my %orig = qw( a 1 b 2 c 3 d 4 e 5 f 6 ); my %new; { my @keys; @new{ @keys } = @orig{ @keys = grep /[adf]/, keys %orig }; } print Dump( { orig => \%orig, new => \%new } ), "\n"; exit 0; __END__ --- new:   a: 1   d: 4   f: 6 orig:   a: 1   b: 2   c: 3   d: 4   e: 5   f: 6

The cake is a lie.
The cake is a lie.
The cake is a lie.

Replies are listed 'Best First'.
Re^2: grep for hash?
by ikegami (Patriarch) on Jul 07, 2009 at 15:47 UTC
    That needlessly makes operand evaluation order relevant. Change
    my @keys; @new{ @keys } = @orig{ @keys = grep /[adf]/, keys %orig };
    to
    my @keys = grep /[adf]/, keys %orig; @new{ @keys } = @orig{ @keys };
    and you have simpler, clearer code.
Re^2: grep for hash?
by rovf (Priest) on Jul 07, 2009 at 15:02 UTC

    I was surprised that this not only works, but also does not complain if strictures are added to the code.

    The code looks ingenious, but I wonder about two aspects: First, you are accessing a list one time as a hash via %NAME, and then the same list as an array, via @NAME. Is this considered accepted practice? Honestly, I hadn't expected it to work with lexically scoped variables, and I'm not sure whether this trick (if I can call it like this) will remain with later Perl versions.

    A more serious problem is the line
    @new{ @keys } = @orig{ @keys = grep /[adf]/, keys %orig };
    where you rely on the fact that @keys gets its value first (from the grep) before it is used to form a slice for @new. I think this is undefined behaviour, isn't it?
    -- 
    Ronald Fischer <ynnor@mm.st>

      All of the references are to the hashes %new and %old; the leading @ and curlies is just the way you name slices. The only array involved in the whole thing is @keys.

      As for relying on the ordering, I think it's pretty safe to count that the rvalue will be computed and available before the lvalue is populated with it.

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

        I think it's pretty safe to count that the rvalue will be computed and available before the lvalue is populated with it.

        In general, no. The container can be placed on the stack before the value it will receive. The assignment only occurs after both the value and the container are on the stack.

        In Perl, operands are always evaluated from left to right, except the operands for assignment operators are always evaluated from right to left. But that's not documented.

        GivenDisinguishes these Interpretations
        Operator Precedence1+2*3(1+2)*3
        -vs-
        1+(2*3)
        Operator Associativity2**3**4(2**3)**4
        -vs-
        2**(3**4)
        Operand Evaluation Orderfoo()+bar()foo() -> bar() -> add
        -vs-
        bar() -> foo() -> add

        Update: I foresaw confusion between operator associativity and operand evaluation order, so I added the table.

Log In?
Username:
Password:

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

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

    No recent polls found