#!/usr/bin/perl ##################### # # A first (and not very satisfactory) look # at the behavior of Perl's increment operator, # in particular the weird behavior of (++$m + $m++). # # See ./quantum_weirdness.txt # # Jim Mahoney # Marlboro College # mahoney@marlboro.edu # # Copywright 2004. This program is free software; you may # redistribute it and/or modify it under the same terms as Perl itself. ######################### use strict; use warnings; my $m; print "\n A look at the increment operators and their side effects.\n\n"; my @perlcode = ( ' $m=20; $m = $m++; ', ' $m=20; $m = ++$m; ', ' $m=20; $m = $m++ + ++$m; ', ' $m=20; $m = ++$m + $m++; ', ' $m=20; $m = $m++ + $m++; ', ' $m=20; $m = ++$m + ++$m; ', ); my @with_post_and_pre = my @with_noop = my @with_look = @perlcode; s/(\S\S)\+\+/pre($1)/g, s/\+\+(\S\S)/post($1)/g for @with_post_and_pre; s/(\S\S\+\+|\+\+\S\S)/noop($1)/g for @with_noop; s/(\S\S\+\+|\+\+\S\S)/look($1)/g for @with_look; foreach my $line (@perlcode, @with_look, @with_post_and_pre, @with_noop){ print("After {$line} \n"); eval $line; print("m is $m in " . \$m . ".\n\n"); } print " - - - - - - - - - - - - - - - - - \n\n"; while (@perlcode){ my $perl = shift @perlcode; my $m_perl = eval $perl; my $watched = shift @with_noop; my $m_watched = eval $watched; if ($m_perl != $m_watched){ print " Quantum weirdness : \n"; print " { $perl } gives m = $m_perl. \n"; print " { $watched } gives m = $m_watched. \n"; print "\n"; } } exit; # --- subroutines ---- # Trying to emulate the pre-increment operator. sub pre { $_[0] = $_[0] + 1; # increment return $_[0]; # return incremented value } # Trying to emulate the post-increment operator. sub post { my $tmp = $_[0]; # make a copy of value $_[0] = $_[0] + 1; # increment return $tmp; # return value before increment } # Print out some info about a value and return it. sub look { print " ...look() gets '$_[0]' in " . \$_[0] . " when m = $m in " .\$m . ".\n"; return $_[0]; } # Do nothing; just return the value passed in. sub noop { return shift; } __END__ ================================================================== The $m++ and ++$m behavior can almost be emulated with post($m) and pre($m), but not quite. I've run this on v5.8.0 on i386-linux and 5.8.1-RC3 on darwin and seen the same answers on both. =========== output ================================================== $ ./increment_detail.pl A look at the increment operators and their side effects. After { $m=20; $m = $m++; } m is 20 in SCALAR(0x805fb64). After { $m=20; $m = ++$m; } m is 21 in SCALAR(0x805fb64). After { $m=20; $m = $m++ + ++$m; } m is 42 in SCALAR(0x805fb64). After { $m=20; $m = ++$m + $m++; } m is 43 in SCALAR(0x805fb64). After { $m=20; $m = $m++ + $m++; } m is 41 in SCALAR(0x805fb64). After { $m=20; $m = ++$m + ++$m; } m is 44 in SCALAR(0x805fb64). After { $m=20; $m = look($m++); } ...look() gets '20' in SCALAR(0x8094f6c) when m = 21 in SCALAR(0x805fb64). m is 20 in SCALAR(0x805fb64). After { $m=20; $m = look(++$m); } ...look() gets '21' in SCALAR(0x805fb64) when m = 21 in SCALAR(0x805fb64). m is 21 in SCALAR(0x805fb64). After { $m=20; $m = look($m++) + look(++$m); } ...look() gets '20' in SCALAR(0x809508c) when m = 21 in SCALAR(0x805fb64). ...look() gets '22' in SCALAR(0x805fb64) when m = 22 in SCALAR(0x805fb64). m is 42 in SCALAR(0x805fb64). After { $m=20; $m = look(++$m) + look($m++); } ...look() gets '21' in SCALAR(0x805fb64) when m = 21 in SCALAR(0x805fb64). ...look() gets '21' in SCALAR(0x8094fb4) when m = 22 in SCALAR(0x805fb64). m is 42 in SCALAR(0x805fb64). After { $m=20; $m = look($m++) + look($m++); } ...look() gets '20' in SCALAR(0x8094fcc) when m = 21 in SCALAR(0x805fb64). ...look() gets '21' in SCALAR(0x8094fcc) when m = 22 in SCALAR(0x805fb64). m is 41 in SCALAR(0x805fb64). After { $m=20; $m = look(++$m) + look(++$m); } ...look() gets '21' in SCALAR(0x805fb64) when m = 21 in SCALAR(0x805fb64). ...look() gets '22' in SCALAR(0x805fb64) when m = 22 in SCALAR(0x805fb64). m is 43 in SCALAR(0x805fb64). After { $m=20; $m = pre($m); } m is 21 in SCALAR(0x805fb64). After { $m=20; $m = post($m); } m is 20 in SCALAR(0x805fb64). After { $m=20; $m = pre($m) + post($m); } m is 42 in SCALAR(0x805fb64). After { $m=20; $m = post($m) + pre($m); } m is 42 in SCALAR(0x805fb64). After { $m=20; $m = pre($m) + pre($m); } m is 43 in SCALAR(0x805fb64). After { $m=20; $m = post($m) + post($m); } m is 41 in SCALAR(0x805fb64). After { $m=20; $m = noop($m++); } m is 20 in SCALAR(0x805fb64). After { $m=20; $m = noop(++$m); } m is 21 in SCALAR(0x805fb64). After { $m=20; $m = noop($m++) + noop(++$m); } m is 42 in SCALAR(0x805fb64). After { $m=20; $m = noop(++$m) + noop($m++); } m is 42 in SCALAR(0x805fb64). After { $m=20; $m = noop($m++) + noop($m++); } m is 41 in SCALAR(0x805fb64). After { $m=20; $m = noop(++$m) + noop(++$m); } m is 43 in SCALAR(0x805fb64). - - - - - - - - - - - - - - - - - Quantum weirdness : { $m=20; $m = ++$m + $m++; } gives m = 43. { $m=20; $m = noop(++$m) + noop($m++); } gives m = 42. Quantum weirdness : { $m=20; $m = ++$m + ++$m; } gives m = 44. { $m=20; $m = noop(++$m) + noop(++$m); } gives m = 43.
syntax highlighted by Perl::Tidy 20060719