develooper Front page | perl.perl5.porters | Postings from December 2011

[perl #3306] DESTROY not called on code reference objects

Thread Previous | Thread Next
From:
=?UTF-8?B?T2xpdmllciBNZW5ndcOp?= via RT
Date:
December 30, 2011 10:55
Subject:
[perl #3306] DESTROY not called on code reference objects
Message ID:
rt-3.6.HEAD-14510-1325253343-1050.3306-14-0@perl.org
Le Dim. Ao�. 17 15:07:59 2003, davem a �crit�:
> About a year ago, Simon Cozens reported a bug to the effect that
> 
>     { my $x = bless sub { }, 'X'; }
>     sub X::DESTROY { print "DESTROYED\n" }
> 
> Doesn't call the destructor.
> 
> Having looked at it, the reason is that the anon sub isn't a closure
> (ie doesn't refer to any outer lexicals. Thus, the CV is shared rather
> than cloned, so its refcnt is >1 when $x is freed.

What we are seeing here is that "sub {}" is a kind of shared constant.
Just like '"foo"' or '1'.

Blessing multiple times the same value multiple time can only lead to
unexpected behavior and I don't a single case where blessing (and
re-blessing) the same non-closure sub would be useful. In general bless
should only succeed on real not-shared references, which in the CODE
case are closures.

So I think that the proper fix for this issue would be that bless die
for non-closure subs as it does in the other constants cases (where it
dies with "Can't bless non-reference value"). The error message would be
"Can't bless non closure sub".
If the user wanted a unique object the workaround (transforming the sub
in a real closure) is easy and obvious as has already been shown in this
ticket.

To mitigate issues with existing code (but I would be interested to see
such usage), we could just warn on the first bless and die only on
re-blessing. But my preference still goes to "die always".

Olivier.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About