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

Array slice out of order

by smark (Acolyte)
on Feb 03, 2005 at 18:27 UTC ( [id://427759]=perlquestion: print w/replies, xml ) Need Help??

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

Fellow monks, Can anyone figure out why this doesn't work as expected?
#!/usr/bin/perl my @m = ('a','b'); my $i = 0; print @m[$i,$i++];
It should print 'aa', correct? Or maybe 'ab' if the ++ is processed early by perl? It prints 'ba'...

Replies are listed 'Best First'.
Re: Array slice out of order
by Roy Johnson (Monsignor) on Feb 03, 2005 at 18:42 UTC
    You've got an lvalue and an rvalue there. lvalues are not converted to rvalues until they have to be. So it sees $i and leaves it alone, then sees $i++ and evaluates it (yielding 0 and incrementing $i), then plugs in the value of $i to use for indexing the array.

    If you change it to

    print @m[$i+0, $i++];
    you'll have two rvalues, and they will have been evaluated from left to right, yielding the 'aa' that you want.

    It doesn't have to work this way — as others point out, it's undefined behavior when side-effects happen — but this is how it is happening here.


    Caution: Contents may have been coded under pressure.
Re: Array slice out of order
by Tanktalus (Canon) on Feb 03, 2005 at 18:30 UTC

    Heheh ... in C, that would be called "undefined behaviour". Any behaviour, including formatting of the author's hard disk (even if not running on the author's machine), is allowed.

    It all depends on the order that perl evaluates the expression. It looks like perl evaluates the subscripts from right to left in this case, so it evaluates the $i++ (incrementing i after putting a zero there), and then evaluates the $i (putting the newly-incremented value of one there), and then splices. Neat!

    Update:Slight clarification (emphasised) (thanks dragonchild and cog)

      Actually, it doesn't evaluate right-to-left for an arbitrary reason.

      The complete expression is evaluated inside-to-outside. The innermost expression is [$i, $i++]. The comma operator, within a list context (which the [] provides), evaluates from right-to-left. (This is different from a scalar context where it evaluates the LHS, discards the value, then evaluates the RHS.)

      It's not clearly spelled out, but you can look at p.108 (for the comma operator) and p.109 (for list contexts in general) of the 3rd ed. Camel.

      Update: Roy Johnson's answer is much better than mine.

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      It still prints 'ab' for print @m[$i++,$i], so it doesn't seem a case of "right to left evaluation" to me...
Re: Array slice out of order
by sh1tn (Priest) on Feb 03, 2005 at 19:00 UTC
    my @m = a..z; my $i = 0; #must be on the right side print @m[$i++,$i++,$i++,$i++,$i];
Re: Array slice out of order
by TomDLux (Vicar) on Feb 04, 2005 at 18:06 UTC

    It only occured to me today that you're wrong. it is impossile for the output to be ab.

    If the left one is evaluated first, the first element in the pair is a. The second element if also a, but $i gets incremented to 1. In this case the result is 'aa'.

    Alternately, if the right one is evaluated first, the second element in the pair is a, and $i gets incremented to 1. The first element is then set to b,for a final result of 'ba'.

    As far as I can see, there would be no way to wind up with 'ab'

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (7)
As of 2024-04-16 17:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found