Re: Puzzling $| behavior
by dirving (Friar) on Oct 07, 2007 at 21:45 UTC
|
Perl's behavior isn't defined when you read the value of a variable and then auto-increment/decrement it later in the same statement. Try doing this instead and you'll get the behavior you expect:
$| = 0;
print "first=$|,";
$|--;
print "second=$|\n";
$| = 1;
print "first=$|,";
$|--;
print "second=$|\n";
In your first case, Perl evaluates the second $|, then decrements it, then evaluates the first one, leading to the unexpected behavior. The reason you don't end up with "-1" is that there is magic associated with $|. It doesn't actually hold a value, it just tracks whether it is set to a non-zero value or not. Try for instance $| = -3; print $| to see this behavior.
Read perlvar and perlop for more information on what is going on here.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Puzzling $| behavior
by ikegami (Patriarch) on Oct 07, 2007 at 23:16 UTC
|
For starters, $|-- is special and may confuse the issue. $|-- toggles $| between 0 and 1. (No idea why)
Secondly, it's bad to modify and use a variable in the same expression because
print "first=", $var, " second=", $var--, "\n";
is basically equivalent to
do {
local @_;
alias $_[0] = "first=";
alias $_[1] = $var;
alias $_[2] = " second=";
my $anon = $var--; # <-- Changes $var *and* $_[1]
alias $_[3] = $anon; # since $_[1] is an alias
alias $_[4] = "\n"; # for $var.
&print;
};
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Puzzling $| behavior
by mwah (Hermit) on Oct 07, 2007 at 21:56 UTC
|
1: $| = 1;
2: print "first=", $|, " second=", $|--, "\n";
the important output will be:
OP (0x824de58) enter
COP (0x81f3290) nextstate
#1 $| = 1
SVOP (0x824dc80) const [6] IV (0x8167cdc) 1
PADOP (0x818ae48) gvsv GV (0x8168894) *|
BINOP (0x8189398) sassign
#
COP (0x824c638) nextstate
OP (0x8250178) pushmark
# 2
SVOP (0x8189428) const [7] PV (0x816881c) "first="
PADOP (0x818c6f0) gvsv GV (0x8168894) *|
SVOP (0x818de00) const [8] PV (0x8168828) " second="
PADOP (0x824ff88) gvsv GV (0x8168894) *|
UNOP (0x824fe50) postdec [4]
SVOP (0x824de38) const [9] PV (0x81688b8) "\n"
LISTOP (0x8250150) print
#
LISTOP (0x824dac0) leave [1]
from where it can be learned that the $| decrement
occurs (postdec [4]) where it should.
Sorry for writing such a mess without checking before :-(
Regards
mwa
/1/ perl -MO=Bblock mysource.pl | [reply] [Watch: Dir/Any] [d/l] [select] |
|
(please correct here me if I'm wrong)
I don't know if perl's documentation defines (as a feature) the order in which arguments are evaluated, but it's simple to check that it really does evaluate them in left-to-right order:
$ perl -le 'print sub{print 1; "x"}->(), sub{print 2; "y"}->()'
1
2
xy
The reason the OP's example is weird is because Perl's argument passing uses aliases whenever possible (as ikegami illustrates below). In the example, an alias to $| gets passed as the second argument. When evaluating the fourth argument, $| is changed. When print finally inspects its arguments, the aliased second argument will report the changed value.
| [reply] [Watch: Dir/Any] [d/l] |
|
I don't know if perl's documentation defines (as a feature) the order in which arguments are evaluated
It's not, but no one has mentioned a system or version where the arguments are evaluated in any order other than left-to-right in past discussions on the subject.
It's technically subject to change since it's not documented, but I find it highly unlikely to change in Perl5.
| [reply] [Watch: Dir/Any] |
|
|
|
Re: Puzzling $| behavior
by cosmicperl (Chaplain) on Oct 07, 2007 at 23:17 UTC
|
$| is either 1 or 1. If it's 0 and you are telling it to change value with $|--, it's go to 1. If this isn't what you want seems to me an if statement is in order.
Lyle | [reply] [Watch: Dir/Any] |
Re: Puzzling $| behavior
by Anonymous Monk on Oct 08, 2007 at 07:24 UTC
|
$x=0;
printf "%d %d %d\n",$x--,$x--,$x--;
Then try the same code (syntax adjusted) in any other language that supprts printf, like C. You will get different answers depending on the implementation. Some compilers give gifferent results depending on optimisation switches (Visual Studio, not gcc). A good reason not to nest ++ or -- in other statements? | [reply] [Watch: Dir/Any] [d/l] |
|
$x=0;
printf "%d %d %d\n",$x,$x--,$x;
Note that even though Perl executed the four operand from left to right, the result is -1 -1 -1.
| [reply] [Watch: Dir/Any] [d/l] [select] |