Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: weaken CODEREF

by dave_the_m (Parson)
on Nov 11, 2013 at 09:14 UTC ( #1061961=note: print w/ replies, xml ) Need Help??


in reply to weaken CODEREF

Its a feature (of sorts) and it's unrelated to weaken(). When an anonymous sub is compiled, a "prototype" sub (CV) is created. At run time, whenever 'sub {...}' is executed, a copy of that prototype CV is made, as you would expect.

However, as an optimisation (with unfortunately visible side effects), if that CV isn't closing over any outer lexicals, the CV isn't copied, it's shared: so its ref count is bumped and a new reference to it is returned. Which is what you're seeing here.

The other common visible side-effect is this:

for (1,2) { push @a, sub {}; my $lex; push @b, sub { $lex }; } bless $a[0]; bless $b[0]; print "$a[1] $b[1]\n";

which outputs

main=CODE(0x1f41648) CODE(0x1f40c88)

Whoops, $a[1] is blessed too.

No-ones thought of a way round this yet, but removing the optimisation would make simple anon subs a lot slower.

Dave.


Comment on Re: weaken CODEREF
Select or Download Code
Re^2: weaken CODEREF
by tobyink (Abbot) on Nov 11, 2013 at 13:07 UTC

    Correctamundo! Usually this optimization doesn't cause any issues, but if you're finding that it does, the solution is to force Perl to close over a variable. A short string or small integer is ideal, as they'll waste very little memory.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1061961]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2014-09-18 19:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (121 votes), past polls