[OT] blessed sub-refs in the symbol table

Matt Lawrence matt.lawrence at virgin.net
Fri Feb 1 11:42:54 GMT 2013

On 01/02/13 09:21, Nicholas Clark wrote:
> 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.
There are other strange effects of this optimisation, e.g. applying 
different attributes to similar anonymous subroutines.

Can anyone enlighten me as to why this seems to fail with scalars?

# bless a SCALAR ref and stick it in the symbol table
*foo = do { bless \(my $x = "Message one"), "Foo" };
sub Foo::DESTROY { say "Goodbye, cruel world" };

say *foo{SCALAR};
# Foo=SCALAR(0x8bb46c0)

*foo = \"Message two";
say $::foo;
# Message two

say *foo{SCALAR}
# SCALAR(0x8ba7f20)
# So the original $::foo is gone, but no DESTROY yet


More information about the london.pm mailing list