Closed p5pRT closed 14 years ago
This problem has been seen on Perl 5.8.3 and 5.8.7. I assume that it happens under other versions as well.
If you try to undef the CODE slot of a glob\, it only halfway works. ref(*foo{CODE}) will still show that it is a code reference\, and UNIVERSAL::can still shows that it is a code reference.
This bug causes problems when Apache::Reload and Class::DBI are used together.
The following code sample demonstrates what I am talking about
-------- #! /usr/bin/perl -l print "Originally foo() is a " . ref(*foo{CODE}); print "Initializing foo()"; *foo = sub {print "hello"}; print "foo() is now a " . ref(*foo{CODE}); print "According to can\, foo is " . main->can("foo"); print "Calling foo()"; foo();
print "Undefining foo()"; $x = *foo; undef &$x; print "foo() is now a " . ref(*foo{CODE}); print "According to can\, foo is " . main->can("foo"); print "Calling foo()"; foo();
__END__ Originally foo() is a Initializing foo() foo() is now a CODE According to can\, foo is CODE(0x8175b24) Calling foo() hello Undefining foo() foo() is now a CODE According to can\, foo is CODE(0x8175b24) Calling foo() --------
The way that this comes into play in the case that I mention is that Apache::Reload attempts to undefine subroutines that have been defined\, but when Class::DBI tries to check whether they are there it is told that they are\, with disasterous results.
On Fri\, Sep 09\, 2005 at 06:11:49PM -0700\, Ben Tilly wrote:
If you try to undef the CODE slot of a glob\, it only halfway works. ref(*foo{CODE}) will still show that it is a code reference\, and UNIVERSAL::can still shows that it is a code reference.
Undefing a sub is not the same as deleting a sub. Internally\, the CV continues to exist\, but its pad and op tree are freed. cf:
$ perl587 -le 'my $x = []; undef @$x; print $x' ARRAY(0x9c7d180) $ perl587 -le 'my $x = sub {}; undef &$x; print $x' CODE(0x8e40bac)
In both cases the thing continues to exist\, but has no useful 'value'.
-- My get-up-and-go just got up and went.
The RT System itself - Status changed from 'new' to 'open'
When I looked at the way the message appeared on the list\, I realized that I forgot to include one line of output. The one where it dies. Here is the program and output with that additional piece of information.
And to clarify the Class::DBI/Apache::Reload conflict that this causes\, load up the page and look at it. You see a web page. Make a trivial modification to the underlying code. You get internal server errors because it can't figure out that there aren't really accessors there for it to go and call.
Cheers\, Ben
#! /usr/bin/perl -l print "Originally foo() is a " . ref(*foo{CODE}); print "Initializing foo()"; *foo = sub {print "hello"}; print "foo() is now a " . ref(*foo{CODE}); print "According to can\, foo is " . main->can("foo"); print "Calling foo()"; foo();
print "Undefining foo()"; $x = *foo; undef &$x; print "foo() is now a " . ref(*foo{CODE}); print "According to can\, foo is " . main->can("foo"); print "Calling foo()"; foo();
__END__ Originally foo() is a Initializing foo() foo() is now a CODE According to can\, foo is CODE(0x8158f10) Calling foo() hello Undefining foo() foo() is now a CODE According to can\, foo is CODE(0x8158f10) Calling foo() Not a CODE reference at - line 16.
On 9/10/05\, Dave Mitchell \davem@​iabyn\.com wrote:
Undefing a sub is not the same as deleting a sub. Internally\, the CV continues to exist\, but its pad and op tree are freed. cf:
One of the items on the todo list is to allow the construct
delete &foo;
I could finish my patch to do it if I could figure out how to delete a CV cleanly from all the stashes where it's referenced... (subs have this tendency to be exported in other stashes.)
@iabyn - Status changed from 'open' to 'rejected'
Migrated from rt.perl.org#37128 (status was 'rejected')
Searchable as RT37128$