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

Good evening Monks,

I have a very low level in Perl and I am trying to do something like:

$i=0; print 'first=' , $i, ', ' if ($i++); print 'middle=', $i, ', ' if ($i++); print 'last=' , $i, ', ' if ($i++); print 'beyond=', $i if $i++;
I was expecting something like (as '++' is AFTER the variable):
middle=1, last=2, beyond=3
While, instead, I get:
middle=2, last=3, beyond=4

I changed my code (first line only) to be:
print 'first=' , $i, ', ' if (++$i); and I get:
first=1, middle=2, last=3, beyond=4
which only adds to my confusion.

Can someone help me and tell me why the $var++ and the ++$var syntaxes do not produce what I was thinking right according to what (I understand to be) are the rules for the ++Var and Var++ syntaxes ? Meaning:
a) null 1 2 3
b) 1 1 2 3

TIA
Gilles

PS: I'm using activeState perl 5.014 under W7/64

Replies are listed 'Best First'.
Re: Auto-increment behaviour, is this normal and why?
by kennethk (Abbot) on Oct 18, 2013 at 18:56 UTC
    The ++ is after variable, so it increments after you test it; however, the print is a separate statement. If you used Compound Statements instead of Statement Modifiers, your code would better reflect the actual flow and would look like:
    $i=0; if ($i++) { print 'first=' , $i, ', '; } if ($i++) { print 'middle=' , $i, ', '; } if ($i++) { print 'last=' , $i, ', '; } if ($i++) { print 'beyond=' , $i, ', '; }
    For what you want, you probably mean:
    $i=0; if ($i++) { print 'first=' , $i - 1, ', '; } if ($i++) { print 'middle=' , $i - 1, ', '; } if ($i++) { print 'last=' , $i - 1, ', '; } if ($i++) { print 'beyond=' , $i - 1, ', '; }
    which is admittedly a little awkward. More natural would be to post-increment after your print, except you clearly intend the incrementation to happen independently of whether the print happens. Perhaps
    $i=0; print 'first=' , $i, ', ' if $i; $i++; print 'middle=', $i, ', ' if $i; $i++; print 'last=' , $i, ', ' if $i; $i++; print 'beyond=', $i if $i; $i++;
    or
    my $i=0; outputter('first', $i++); outputter('middle', $i++); outputter('last', $i++); outputter('beyond', $i++); sub outputter { my ($txt, $i) = @_; print "$txt=$i, " if $i; }

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Dear Kenneth,

      Thank you for your answer.

      So if understand what you expressed by "the print is a separate statement", the process is executing the following steps:

      1. it tests the if condition
      2. it incréments
      3. it prints only if (1)

      Thus because in the 1st case the if was false, the increment is done and the print not.
      So at instruction 2 $i is already 1 and incremented to 2 before print, not after on the contrary of what I thought.
      Then, as you shown me, when I write:
      $i=0; for $lbl (qw/first middle last beyond/) {print $lbl.':',$i-1,',' if $i++}
      I get what I expect:
      middle:1,last:2,beyond:3,

      All right, I was misunderstanding the time sequence when the increment applies with the if modifier (I still prefer it, it's shorter, I just need to learn to control it).

      Thank you again very much.

      Gilles.

Re: Auto-increment behaviour, is this normal and why?
by toolic (Bishop) on Oct 18, 2013 at 18:27 UTC