$x will never be assigned, because perl dies before it could assign the result of the or operation.
Could you explain or expand on that statement, please? I still cannot figure out why that would be true. If it were the high precedence ||, then I would 100% agree, because perl would evaluate the 0 then then die before evaluating the assignment operator. But or has lower precedence than =, so the assignment should be processed first.
And I do remember seeing many posts that the compile-time vs run-time effects of my make it more confusing, as is obvious from it not passing strict if I try to use the $x in the die without separating the my out. But the conditional my considerations are separate from the assignment considerations, I would think. If I am wrong, then how have I misunderstood the precedence table as published, which seems to me to very clearly say that assignment has higher precedence than or.
Digging into examples, trying to prove myself wrong, and better explain myself if I am right:
When I simplify your example farther, but with the my separated from the conditional, I see:
C:\Users\Peter>perl -Mstrict -le "my $x; $x = 0 or die $x"
0 at -e line 1.
And this makes sense to me if I look at the B::Deparsed version, too:
C:\Users\Peter>perl -MO=Deparse -Mstrict -le "my $x; $x = 0 or die $x"
BEGIN { $/ = "\n"; $\ = "\n"; }
use strict;
my $x;
die $x unless $x = 0;
-e syntax OK
... where
$x=0 presumably has to be executed before the
unless can be decided, which then decides whether or not
die gets to run. But die has access to the $x variable with value 0.
Adding B::Deparse to your example
C:\Users\Peter>perl -MO=Deparse -Mstrict -w -E "sub false { 0 } my $x=
+false or die 'Died'; say 'not reached';"
BEGIN { $^W = 1; }
use strict;
use feature 'current_sub', 'bitwise', 'evalbytes', 'fc', 'postderef_qq
+', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';
sub false {
0;
}
die 'Died' unless my $x = false();
say 'not reached';
-e syntax OK
... which shows a similar structure to my simplified example, so I don't think I'm completely out of line in my interpretation
Because of strict, I cannot just do die 'Died',$x in your example. But if I move the my outside the conditional:
C:\Users\Peter>perl -Mstrict -w -E "sub false { 0 } my $x; $x=false or
+ die 'Died',$x; say 'not reached';"
Died0 at -e line 1.
The assignment happens; if it didn't, the results would have not had the 0 in the printout, and would have warned about unintialized value, because $x would have been undefined.
Now, if I change the or to || in your the oneliner with $x in the die, it deparses differently:
C:\Users\Peter>perl -MO=Deparse -Mstrict -w -E "sub false { 0 } my $x=
+false || die 'Died',$x; say 'not reached';"
Global symbol "$x" requires explicit package name (did you forget to d
+eclare "my $x"?) at -e line 1.
-e had compilation errors.
BEGIN { $^W = 1; }
use strict;
use feature 'current_sub', 'bitwise', 'evalbytes', 'fc', 'postderef_qq
+', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';
sub false {
0;
}
my $x = false() || die('Died', ${'x'});
say 'not reached';
C:\Users\Peter>perl -MO=Deparse -Mstrict -w -E "sub false { 0 } my $x;
+ $x=false || die 'Died',$x; say 'not reached';"
BEGIN { $^W = 1; }
use strict;
use feature 'current_sub', 'bitwise', 'evalbytes', 'fc', 'postderef_qq
+', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';
sub false {
0;
}
my $x;
$x = false() || die('Died', $x);
say 'not reached';
-e syntax OK
... and there, I would agree that the die occurs before the assignment for
||.
If I compare the B::Concise's terse output from the or vs || with your example but with the two precendences on the logic (so the my is still attached to the conditional), the sassign happens after the LOGOP with ||, but before the LOGOP with or, which I again interpret to mean that the assignment should happen with or:
C:\Users\Peter>perl -MO=Concise,-terse,-exec -Mstrict -w -E "sub false
+ { 0 } my $x=false || die 'Died'; say 'not reached';"
OP (0x2a1c6b8) enter
COP (0x2a85b00) nextstate
OP (0xfdfb00) pushmark
PADOP (0xfdfac0) gv IV (0x105fb40) \&main::false
UNOP (0x2a85cf0) entersub
LOGOP (0x2a85be8) or
OP (0x2a85c78) pushmark
SVOP (0x2a85cb0) const [4] PV (0x105f618) "Died"
LISTOP (0x2a85c30) die [3]
OP (0xfdfb40) padsv [1]
BINOP (0x2a85b60) sassign
COP (0x2a85998) nextstate
OP (0x2a85a40) pushmark
SVOP (0x2a85a78) const [5] PV (0x105f5b8) "not reached"
LISTOP (0x2a859f8) say
LISTOP (0x2a85ab8) leave [1]
-e syntax OK
C:\Users\Peter>perl -MO=Concise,-terse,-exec -Mstrict -w -E "sub false
+ { 0 } my $x=false or die 'Died'; say 'not reached';"
OP (0x2a249d8) enter
COP (0x2a76030) nextstate
OP (0xfc08e0) pushmark
PADOP (0xfc08a0) gv IV (0x103e770) \&main::false
UNOP (0x2a76220) entersub
OP (0xfc0920) padsv [1]
BINOP (0x2a761d8) sassign
LOGOP (0x2a760d0) or
OP (0x2a76160) pushmark
SVOP (0x2a76198) const [4] PV (0x103e1e8) "Died"
LISTOP (0x2a76118) die [3]
COP (0x2a75ec8) nextstate
OP (0x2a75f70) pushmark
SVOP (0x2a75fa8) const [5] PV (0x103e248) "not reached"
LISTOP (0x2a75f28) say
LISTOP (0x2a75fe8) leave [1]
-e syntax OK
I have tried every combination I can think of, and everything I see would seem to indicate that, my notwithstanding, the assignment happens. If your claim was really about the my in the original post, rather than the assignment, I would agree with you; but if it's about the assignment as you phrased it, then so far, I haven't convinced myself.
But I understand that I am not an expert on the B:: modules' outputs, so maybe I'm misinterpreting things. But I thought I understood the precedence. If I am mistaken, I would appreciate learning where I've misinterpreted things.