LanX has asked for the wisdom of the Perl Monks concerning the following question:

I have a problem to understand the underlined passage in perlsub about Constant Functions:

If the result after optimization and constant folding is either a constant or a lexically-scoped scalar which has no other references, then it will be used in place of function calls made without &

Could anyone please give me an example?

Running this code gives me a warning "Constant subroutine inl redefined" prooving that the first inl() was considered constant.

sub inl () {"inline"} sub inl () { my $lex;} print inl;

But this doesn't mention "constant"...!?!

sub inl () { my $lex;} sub inl () {"inline"} print inl;

So what kind of scoped lexicals are meant?

Cheers Rolf

UPDATE: I suppose this is either a bug in 5.10 or an error in the perl docs...

Replies are listed 'Best First'.
Re: Inlining a "lexically-scoped scalar which has no other references"
by dave_the_m (Monsignor) on Sep 28, 2009 at 04:47 UTC
    Neither a bug nor a doc error:
    # same as 'use constant FOO => 10' BEGIN { my $lex = 10; *FOO = sub () { $lex }; }

    Dave.

      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.

        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

Re: Inlining a "lexically-scoped scalar which has no other references"
by ikegami (Patriarch) on Sep 28, 2009 at 00:20 UTC

    Right off the bat, the docs are unclear. Other than which reference? The pad's?

    And then there's the issue that my $lex; produces a lexical var, but isn't one itself. Does that matter?

    Control:

    >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" sub with_proto() { 4 } sub without_proto { 4 } with_proto(); without_proto(); <---- Note absence of "with_proto" 5 <#> gv[*without_proto] s <---- Not constant

    Tests:

    >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" sub with_proto() { my $lex } sub without_proto { my $lex } with_proto(); without_proto(); 4 <#> gv[*with_proto] s <---- Not constant 8 <#> gv[*without_proto] s <---- Not constant >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" my $lex = 4; sub with_proto() { $lex } sub without_proto { $lex } with_proto(); without_proto(); 8 <#> gv[*with_proto] s <---- Not constant c <#> gv[*without_proto] s <---- Not constant >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" { my $lex = 4; sub with_proto() { $lex } } { my $lex = 4; sub without_proto { $lex } } with_proto(); without_proto(); i <#> gv[*with_proto] s <---- Not constant m <#> gv[*without_proto] s <---- Not constant

    Bah, let's try references.

    >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" sub with_proto() { \my $lex } sub without_proto { \my $lex } with_proto(); without_proto(); 4 <#> gv[*with_proto] s <---- Not constant 8 <#> gv[*without_proto] s <---- Not constant >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" my $lex = 4; sub with_proto() { \$lex } sub without_proto { \$lex } with_proto(); without_proto(); 8 <#> gv[*with_proto] s <---- Not constant c <#> gv[*without_proto] s <---- Not constant >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" { my $lex = 4; sub with_proto() { \$lex } } { my $lex = 4; sub without_proto { \$lex } } with_proto(); without_proto(); i <#> gv[*with_proto] s <---- Not constant m <#> gv[*without_proto] s <---- Not constant

    lvalue?

    >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" sub with_proto() :lvalue { my $lex } sub without_proto :lvalue { my $lex } with_proto(); without_proto(); 4 <#> gv[*with_proto] s 8 <#> gv[*without_proto] s >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" my $lex = 4; sub with_proto() :lvalue { $lex } sub without_proto :lvalue { $lex } with_proto(); without_proto(); 8 <#> gv[*with_proto] s c <#> gv[*without_proto] s >type test.pl && perl -MO=Concise,-exec test.pl 2>&1 | find "proto" { my $lex = 4; sub with_proto() :lvalue { $lex } } { my $lex = 4; sub without_proto :lvalue { $lex } } with_proto(); without_proto(); i <#> gv[*with_proto] s m <#> gv[*without_proto] s

    No more ideas.

      thx, ikegami these are pretty much all the tests I already ran. 8-|

      I think it's an old optimization feature that got dropped/lost, without updating the docs.

      If anyone has access to a fairly old perl5 version, it would be nice to know what these test produce... He doesn't need to use B::Concise, it's documented that redefining a "constant function" always has to give a warning!

      so plz, just run this code, and check for a warning:

      no warnings; my $lex = 4; # file scoped lexical #--- normal # inner scope sub with_proto () { my $lex } # outer scope { my $lex = 4; sub with_proto() { $lex } } # file scope sub with_proto() { $lex } #--- reference # inner scope sub with_proto() {\ my $lex } # outer scope { my $lex = 4; sub with_proto() {\ $lex } } # file scope sub with_proto() {\ $lex } #------ lvalue #--- normal # inner scope sub with_proto() :lvalue { my $lex } # outer scope { my $lex = 4; sub with_proto() :lvalue { $lex } } # file scope sub with_proto() :lvalue { $lex } #--- reference # lvalue references are not feasible, because of # "Can't modify single ref constructor in lvalue subroutine" #------ overriding constant function throws always a warning sub with_proto () {4} # uncommenting garanties a warning # sub with_proto () {5}

      Cheers Rolf

        The oldest I have is 5.6.0, but it doesn't give a warning even when uncommenting the last line.

        Changing no warnings; to use warnings; shows that the following creates a constant in 5.6.0 and 5.6.1, but not in 5.8.0:

        sub with_proto () { my $lex }
        >c:\progs\perl560\bin\perl test.pl Use of uninitialized value at test.pl line 12. Constant subroutine with_proto redefined at test.pl line 12. Subroutine with_proto redefined at test.pl line 16. Subroutine with_proto redefined at test.pl line 20. Subroutine with_proto redefined at test.pl line 25. Subroutine with_proto redefined at test.pl line 29. Subroutine with_proto redefined at test.pl line 36. Subroutine with_proto redefined at test.pl line 41. Subroutine with_proto redefined at test.pl line 45. Subroutine with_proto redefined at test.pl line 55. Constant subroutine with_proto redefined at test.pl line 58. >c:\progs\perl561\bin\perl test.pl Use of uninitialized value at test.pl line 12. Constant subroutine with_proto redefined at test.pl line 12. Subroutine with_proto redefined at test.pl line 16. Subroutine with_proto redefined at test.pl line 20. Subroutine with_proto redefined at test.pl line 25. Subroutine with_proto redefined at test.pl line 29. Subroutine with_proto redefined at test.pl line 36. Subroutine with_proto redefined at test.pl line 41. Subroutine with_proto redefined at test.pl line 45. Subroutine with_proto redefined at test.pl line 55. Constant subroutine with_proto redefined at test.pl line 58. >c:\progs\perl580\bin\perl test.pl Subroutine with_proto redefined at test.pl line 12. Subroutine with_proto redefined at test.pl line 16. Subroutine with_proto redefined at test.pl line 20. Subroutine with_proto redefined at test.pl line 25. Subroutine with_proto redefined at test.pl line 29. Subroutine with_proto redefined at test.pl line 36. Subroutine with_proto redefined at test.pl line 41. Subroutine with_proto redefined at test.pl line 45. Subroutine with_proto redefined at test.pl line 55. Constant subroutine with_proto redefined at test.pl line 58.

        Update: I identified the wrong one. Fixed.