Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

Re: weaken CODEREF

by dave_the_m (Prior)
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.


Replies are listed 'Best First'.
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?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1061961]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (8)
As of 2018-04-24 18:59 GMT
Find Nodes?
    Voting Booth?