in reply to Re: Inlining a "lexically-scoped scalar which has no other references"
in thread Inlining a "lexically-scoped scalar which has no other references"

That's cool:

perl -MO=Deparse -e"BEGIN{ my $x = 12345; *Foo = sub(){ $x } }; print +Foo" sub BEGIN { my $x = 12345; *Foo = sub () { $x; } ; } print 12345; -e syntax OK

But why is the BEGIN block necessary?:

perl -MO=Deparse -e"{ my $x = 12345; *Foo = sub(){ $x }; } print Foo() +" { my $x = 12345; *Foo = sub () { $x; } ; } print Foo(); -e syntax OK

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.
RIP PCW It is as I've been saying!(Audio until 20090817)

Replies are listed 'Best First'.
Re^3: Inlining a "lexically-scoped scalar which has no other references"
by ikegami (Patriarch) on Sep 28, 2009 at 05:21 UTC

    But why is the BEGIN block necessary?:

    You can't compile a subroutine call into a constant if the subroutine hasn't been made into a constant yet

      So even though the sub declaration has been seen before you get to the call to it, it hasn't yet been compiled?


      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.

        No it hasn't. You seem to be confusing Foo with the anonymous sub

        1. BEGIN { ... } is compiled.
          1. my $x = 12345; is compiled.
          2. *Foo = sub(){ $x }; is compiled.
        2. BEGIN { ... } is executed.
          1. my $x = 12345; is executed.
          2. *Foo = sub(){ $x }; is executed. ⇐ &Foo is declared and defined here.
        3. print Foo() is compiled. ⇐ &Foo is known to be constant.
        4. [ Execution phase starts ]
        5. print 12345 is executed.

        vs

        1. { ... } is compiled.
          1. my $x = 12345; is compiled.
          2. *Foo = sub(){ $x }; is compiled.
        2. print Foo() is compiled. ⇐ &Foo is implicitly declared and called as a plain sub here.
        3. [ Execution phase starts ]
        4. { ... } is executed.
          1. my $x = 12345; is executed.
          2. *Foo = sub(){ $x }; is executed. ⇐ &Foo is defined here.
        5. print &Foo() is executed.

        In fact, the prototype is always completely ignored if the subroutine call is compiled before the prototype is added.

        *Foo = sub($) { print "$_[0]\n" }; sub Bar($) { print "$_[0]\n" } my @array = qw( a b c ); Foo(@array); # a Bar(@array); # 3
        Since it used to work like you (and me) suggest in 5.6, I suppose some aspects of "constant folding" and/or "reference counting" changed slightly in between.

        Maybe due to another bugfix? Who knows...

        Anyway, IMHO the docs should be updated to be clearer in this respect.

        Cheers Rolf