[OT] blessed sub-refs in the symbol table

Nicholas Clark nick at ccl4.org
Fri Feb 1 09:21:27 GMT 2013


On Thu, Jan 31, 2013 at 11:12:30AM +0000, David Cantrell wrote:
> I am most disappointed to find that if you put a blessed sub-ref in the
> symbol table and then replace it, its DESTROY method doesn't get called
> straight away:
> 
> package Immortal;
> 
> sub new { return bless sub { print "called the object\n" }, shift; }
> sub DESTROY { print "called DESTROY\n"; }
> 1;
> 
> $ perl -MImmortal -e '*Foo::bar = Immortal->new(); Foo::bar(); *Foo::bar = sub {print "blargh\n"}; Foo::bar();'
> called the object
> blargh
> called DESTROY
> 
> looks like the blessed sub continues to exist right to the end of the
> process, even though all references to it have gone away.  Is this a bug?

Yes, in as much as it's an optimisation that goes too far. The internals cheat
to avoid copying subroutines (that as not closures). So, it's the same
reference each time. Even if you bless it:

$ perl -MImmortal -le 'print Immortal->new() for 1 ..3'
Immortal=CODE(0x100818088)
Immortal=CODE(0x100818088)
Immortal=CODE(0x100818088)

The right solution probably involves unwinding this optimisation, either
making CVs cheap to clone, or putting in another level of indirection so
that the addresses (and the part that you bless) are not shared, but the
expensive stuff is.

Nicholas Clark


More information about the london.pm mailing list