Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl increment operator

Tags:

perl

$a = 10; 
$b = (++$a) + (++$a) + (++$a);
print $b;

I am getting the answer 37. Can anybody explain how this operation is proceeding and how the result is getting 37.

As per my logic it should be 36:

(++$a) + (++$a) + (++$a)
   11  +    12  +    13  = 36

But I am getting the answer 37

like image 926
Abhishek Saha Avatar asked Apr 21 '17 15:04

Abhishek Saha


2 Answers

Perl's is executing this as

( ( $a = $a + 1 ) + ( $a = $a + 1 ) ) + ( $a = $a + 1 )

You have even put the ++$a in parentheses so to say that they should happen first, before the additions, although they are of higher priority anyway

This is centred around the fact that the assignment operator = returns its first operand, which allows operations like

(my $x = $y) =~ tr/A-Z/a-z/

If the result of the assignment were simply the value copied from $y to $x then the tr/// would cause a Can't modify a constant item or the equivalent, and it would have no effect on what was stored in either variable

Here is the variable $a, and the execution is as follows

  • Execute the first increment, returning $a
    $a is now 11

  • Execute the second increment, returning $a again
    $a is now 12

  • Execute the first addition, which adds what was returned by the two increments—both $a
    $a is 12, so $a + $a is 24

  • Execute the third increment, returning $a again
    $a is now 13

  • Execute the second addition, which adds the what was returned by the first addition (24) and the third increment ($a)
    $a is 13, so 24 + $a is 37

Note that this should not be relied on. It is not documented anywhere except to say that it us undefined, and the behaviour could change with any release of Perl

like image 169
Borodin Avatar answered Oct 11 '22 09:10

Borodin


As a complement to mob and Borodin's answer, you can see what's happening clearly if you think about how the operations are interacting with the stack and recognize that preinc returns the variable, not its value.

op | a's value | stack
$a | 10        | $a
++ | 11        | $a
$a | 11        | $a $a
++ | 12        | $a $a
+  | 12        | 24
$a | 12        | 24 $a
++ | 13        | 24 $a
+  | 13        | 37
like image 25
ysth Avatar answered Oct 11 '22 07:10

ysth