<Update> After writing this, I realize that it makes no difference that ++$i returns an alias. But I'm too lazy to rewrite the whole thing. The main point is the order in which you evaluate the arguments to the addition operation in those big expressions.</Update> Update2: changed my example so that aliases *did* make a difference. Thanks ysth++.

Statements like yours (with multiple assignments to $i in a single statement) are confusing/unpredictable because there are aliases involved. Preincrement ++$i returns an alias to $i, while postincrement $i++ returns just a plain old value. You can see that this is the case:

sub foo { print \$_[0], $/ } foo($i); # SCALAR(0x81526f0) foo(++$i); # SCALAR(0x81526f0) foo($i++) # SCALAR(0x8151c28)
Now that you know aliases are involved, it's a simple matter of just following the execution.. No magic involved.

So let's look an example:

$i = 0; $i = ++$i + ++$i + $i++ + ++$i;
First, recall that addition is left-associative. Also, check that when evaluating an addition, perl evaluates the left argument before the right argument. At least, that's how it happens in my perl. If there is anything "undefined" about your test cases, it is this part, not the fact that you are using increment operators. So here's how perl evaluates this statement:

value of $iexpressionnext thing to evaluate
0((++$i + ++$i) + $i++) + ++$i First ++$i sets $i to 1, returns alias to $i
1((alias + ++$i) + $i++) + ++$i Second ++$i sets $i to 2, returns alias to $i
2((alias + alias) + $i++) + ++$i contents of $i + contents of $i = 4
2(     4         + $i++) + ++$i Third $i++ returns 2, sets $i to 3
3(     4       + 2) + ++$i 4 + 2 = 6
3                6        + ++$i Fourth ++$i sets $i to 4, returns alias
4                6        + alias 6 + contents of $i = 10
4                         10

Now hopefully you agree with what everyone has been saying, that assigning to a variable multiple times while using its value in the same statement is really not worth it. But I wouldn't say that it's black magic, once you understand about aliasing.

It's up to you to decide it perl will ever do anything other than left-to-right evaluation of arguments to the addition operator. I guess if perl wants to reserve the right to do something else, you'll have to respect that.

blokhead


In reply to Re: Auto Increment "magic" Inquiry by blokhead
in thread Auto Increment "magic" Inquiry by brusimm

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.