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:
Now that you know aliases are involved, it's a simple matter of just following the execution.. No magic involved.sub foo { print \$_[0], $/ } foo($i); # SCALAR(0x81526f0) foo(++$i); # SCALAR(0x81526f0) foo($i++) # SCALAR(0x8151c28)
So let's look an example:
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:$i = 0; $i = ++$i + ++$i + $i++ + ++$i;
| value of $i | expression | next 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
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |