in reply to Re: my (0?$a:$b): a koan
in thread my (0?$a:$b): a koan

Your version is indeed simpler. I had put the sub call in there to see if I could use a parameter for the ternary test (Perl gets angry about your trying to lexicalize @_ if you do that), but failed to remove it.

do you have an explanation for why B::Deparse gets it wrong?
B::Deparse walks through the op-tree reconstructing a Perl program, and I'm guessing that its author didn't anticipate whatever weird optree you get from a ternary inside a "my". That, or it gets defeated by constant folding, just like here:
$ perl -MO=Deparse -e 'print 0?$a:$b' print $b;

Replies are listed 'Best First'.
Re^3: my (0?$a:$b): a koan
by LanX (Saint) on May 04, 2011 at 20:10 UTC
    > or it gets defeated by constant folding

    thats the point, compare the optree of my (0?$a:$b)="X" with my ($b)="X".

    Deparse has no chance to see any difference

    lanx:~$ perl -MO=Concise -e 'my (0?$a:$b)="X";print $a' c <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 7 <2> aassign[t3] vKS ->8 - <1> ex-list lK ->5 3 <0> pushmark s ->4 4 <$> const[PV "X"] s ->5 - <1> ex-list lK ->7 5 <0> pushmark s ->6 6 <0> padsv[$b:1,2] lPRM*/LVINTRO ->7 8 <;> nextstate(main 2 -e:1) v:{ ->9 b <@> print vK ->c 9 <0> pushmark s ->a a <0> padsv[$a:1,2] l ->b -e syntax OK
    lanx:~$ perl -MO=Concise -e 'my ($b)="X";print $a' c <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 7 <2> aassign[t2] vKS ->8 - <1> ex-list lK ->5 3 <0> pushmark s ->4 4 <$> const[PV "X"] s ->5 - <1> ex-list lK ->7 5 <0> pushmark s ->6 6 <0> padsv[$b:1,2] lPRM*/LVINTRO ->7 8 <;> nextstate(main 2 -e:1) v:{ ->9 b <@> print vK ->c 9 <0> pushmark s ->a - <1> ex-rv2sv sK/1 ->b a <#> gvsv[*a] s ->b -e syntax OK

    Note line a: In the first example $a is coded as entry "$a" from a lexical pad and in the second it's the scalar value of glob *a from a symbol table.

    IMHO you found a case where the compiler should better warn about undefined behavior.

    Cheers Rolf

    UPDATE: we had a discussion about this just few weeks ago, but I can't find it. Take this instead: 'my' with 'if 0' retains old value

    UPDATE: And here the warning I'm missing:

    perl -wce 'my $a if 0; print $a' Deprecated use of my() in false conditional at -e line 1. -e syntax OK

    UPDATE: Found it! see A curious case of of my() and Re^4: A curious case of of my() (What is GLOBAL?)

      Nice -- it's a kind of clever inside-out way to say
      my $a if 0; my $b = 3;
      EDIT: As seen with this:
      $a=1; $b=2; sub x { my (0?$a:$b) = shift; print"a=$a\nb=$b\n"; $a=shift } x(3,30); x(4,40); __END__ # OUTPUT: a= b=3 a=30 b=4

        Ok, now that just confuses the fuck out me.

        Obviously this is a convoluted use of my and so I shouldn't worry about it too much. But these results don't match the explanation you gave earlier. If the theory is that both $a and $b get assigned a lexical at the beginning of the sub, than $a should be undef every sub call.

        $a=1; $b=2; sub x { my (0?$a:$b) = shift; print"a=$a\nb=$b\n"; $a=shift } x(3,30); x(4,40); x(5,50); __END__ #Output a= b=3 a=30 b=4 a=40 b=5
Re^3: my (0?$a:$b): a koan
by BrowserUk (Patriarch) on May 04, 2011 at 20:00 UTC
    I'm guessing that its author didn't anticipate whatever weird optree you get from a ternary inside a "my".

    There is no "weird optree". By the time Deparse gets its hands on the optree, the ternary has been optimised away.

    What's left is exactly the same as if the ternary (and $a) had never existed in the source.

    If there is a bug, then it is that the optimisation doesn't undo the local declaration of $a.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.