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.

Replies are listed 'Best First'.
Re^2: weaken CODEREF
by tobyink (Canon) 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