Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

References for ano subs fixed at compile time?

by LanX (Canon)
on Jun 18, 2013 at 18:54 UTC ( #1039629=perlquestion: print w/ replies, xml ) Need Help??
LanX has asked for the wisdom of the Perl Monks concerning the following question:

Hi

I'm pretty sure the answer is yes, but to be sure:

Are the references to anonymous code blocks in Perl always constant, because they are fixed at compile time?

DB<115> sub tst (&) { print "$_[0]\n" } DB<116> tst {1,2,3,4} for 1..5 CODE(0xa396560) CODE(0xa396560) CODE(0xa396560) CODE(0xa396560) CODE(0xa396560)

Is it reliably so? I took a look at B::Concised opcode output and as far as could see it seemed so...

Please note that it is not the case for anonymous hashes

DB<118> sub tst (%) { print "$_[0]\n" } DB<119> tst {1,2,3,4} for 1..5 HASH(0xa3963f0) HASH(0xa396940) HASH(0xa396720) HASH(0xa3966c0) HASH(0xa3963f0)

Cheers Rolf

( addicted to the Perl Programming Language)

Comment on References for ano subs fixed at compile time?
Select or Download Code
Re: References for ano subs fixed at compile time? (no)
by Anonymous Monk on Jun 18, 2013 at 19:29 UTC

    Are the references to anonymous code blocks in Perl always constant, because they are fixed at compile time?

    No and no; its just another variable. consider

    $ perl -le " for(1..3){ my$f=$_; print\$f; }" SCALAR(0x99b824) SCALAR(0x99b824) SCALAR(0x99b824)

    versus

    $ perl -le " sub ff { my $f = $_; return \$f } print ff() for 1..3;" SCALAR(0x3f9bcc) SCALAR(0x3f9bbc) SCALAR(0x3f9bcc)

    What perl does, how perl optimizes, how perl reuses allocated memory, depends on what the code does

      I was talking about CODE-refs not SCALARs!

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        I was talking about CODE-refs not SCALARs!

        Same difference, perl reuses references as it sees fit

Re: References for ano subs fixed at compile time? (sorta)
by tye (Cardinal) on Jun 18, 2013 at 20:03 UTC

    If a sub doesn't close over any lexicals, than I bet that refs to it will be constant. If subs close over lexicals (or represent different code), than the refs can't be constant unless the refs have non-overlapping lifespans.

    DB> sub test(&) { my( $c ) = @_; print 0+$c,$/; return $c } DB> ;{ my($a,$b); test {$a}; test {$b} } 14808916 14808916 DB> ;{ my($a,$b); my $c = test {$a}; test {$b} } 15512116 15512804 DB> ;{ my @a; for(1..3){ my $a; push @a, test {$a} } } 15513028 15511044 15513252

    - tye        

      the last case is the interesting one for me, the coderef of a block at a fixed position (and therefore the same code). I don't care if other blocks get the same ref after this one gets destroyed.

      And my test with your code shows that the ref is fix if its not returned:

      DB<123> sub test(&) { my( $c ) = @_; print 0+$c,$/; return $c } DB<124> ;{ my @a; for(1..3){ my $a; push @a, test {$a} } } 145187472 145182504 144725160 => "" DB<125> sub test(&) { my( $c ) = @_; print 0+$c,$/} DB<126> ;{ my @a; for(1..3){ my $a; push @a, test {$a} } } 145184216 145184216 145184216 => ""

      So the ref is chosen dynamically from a pool of available refs, it can be the last one if it has been released before.

      Thx! =)

      UPDATE

      OK the following code shatters all my hopes that I found an answer to an old question ...

      DB<155> sub tst2(&) { my( $c ) = @_; print &$c,":\t",0+$c,$/;return +$c} DB<156> sub tst1(&) { my( $c ) = @_; print &$c,":\t",0+$c,$/;} DB<157> ;{ my $b; for my $a (1..3){tst1 {$a} ; $b=tst2 {42} if $a==1 + } } 1: 145234328 42: 145234328 2: 141318480 3: 141318480

      it doesn't matter how tst1() deals with the coderef, any later coderef generation might bind the address and disable it for other use.

      > If a sub doesn't close over any lexicals, than I bet that refs to it will be constant.

      Nope it doesn't matter if there are closed over variables, unfortunately you loose your bet...

      DB<158> ;{ my $b; for my $a (1..3){tst1 {1} ; $b=tst2 {2} if $a==1 } + } 1: 141317840 2: 141317840 1: 141318608 1: 141318608

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        Nope it doesn't matter if there are closed over variables, unfortunately you loose your bet...

        To quote myself, with emphasis added:

        If subs close over lexicals (or represent different code)

        "sub {1}" and "sub {2}" are two different subroutines, even when you use prototypes to make the "sub" keyword implied rather than explicit.

        - tye        

Re: References for ano subs fixed at compile time?
by Eily (Hermit) on Jun 18, 2013 at 21:24 UTC

    I ran a few tests after Anonymous Monk's post with

    $\=$/; sub tst { print shift } sub ptst(&) { print shift } sub ff { tst sub {1, 2, 3,} } ff for (1..3); sub ff { print sub {1, 2, 5,} } ff for (1..3); sub ff { ptst {1, 2, 4,} } ff for (1..3);

    Which gives in the debugger:

    DB<1> $\=$/; DB<2> sub tst { print shift } DB<3> sub ptst(&) { print shift } DB<4> sub ff { tst sub {1, 2, 3,} } ff for (1..3); CODE(0x2d1c1f8) CODE(0x2d1c840) CODE(0x2d1c828) DB<5> sub ff { print sub {1, 2, 5,} } ff for (1..3); CODE(0x2d1c330) CODE(0x2d1c330) CODE(0x2d1c330) DB<6> sub ff { ptst {1, 2, 4,} } ff for (1..3); CODE(0x2d1c8a0) CODE(0x2d1c930) CODE(0x2d1c8e8)

    Though there are still things I don't get (like the fact that user function versus core function matters), I interpreted it as proving AM right. Except I ran the following code as a file instead of in the debugger.

    $\=$/; sub ptst(&) { print shift } sub ff {ptst {1, 2, 3, 4,} } ff for (1..3); ptst {1, 2, 3, 4,};

    With the output:

    CODE(0x20f2b8) CODE(0x20f2b8) CODE(0x20f2b8)

    Where you'd get different references with a (%) prototype for ptst. I guess perl is just too smart for me.

Re: References for ano subs fixed at compile time?
by dave_the_m (Parson) on Jun 18, 2013 at 22:51 UTC
    Here's how it it works. Consider the following code:
    $f = sub { .... };
    At compile time, the code within {} is compiled into a prototype anonymous sub (CV), which is squirrelled away somewhere. At run time, the action of sub {...} is to make a copy of that sub (allocating a new CV), and then return a reference to that new CV.

    As an optimisation, if the sub isn't a closure, then rather than copying the CV, a reference is just returned to the original prototype CV. This optimisation isn't perfect; in particular if one blesses $f, then the prototype CV gets blessed, and any new executions of that $f = sub {...} assignment get a blessed coderef.

    Finally, note that perl maintains a pool of spare CVs; when one is freed, it gets returned to the pool and that may get reused soon.

    Of course, these are implementation details which are subject to change.

    Dave.

      Demonstration:
      sub f(&) { my ($cr) = @_; push @keep_alive, $cr; say $cr; } my $x = '...'; f { '...' } for 1..2; f { $x } for 1..2;
      CODE(0x3396f4) \ same for non-capturing CODE(0x3396f4) / CODE(0x24b1cc) \ different for capturing CODE(0x338c04) /

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1039629]
Approved by BrowserUk
Front-paged by BrowserUk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2014-07-10 07:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (202 votes), past polls