Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Removing subroutines from symbol tables

by Ovid (Cardinal)
on Nov 19, 2005 at 07:08 UTC ( [id://510050]=perlquestion: print w/replies, xml ) Need Help??

Ovid has asked for the wisdom of the Perl Monks concerning the following question:

I'd swear I've asked this question, but since I can't find the post, here's hoping I didn't :)

Basically, deleting subroutines from a symbol table seems a bit buggy, but I don't know if this behavior is documented or not.

#!/usr/bin/perl -l sub this { 'this' } print this; undef &main::this; # undefine the code slot print main->can('this') ? 'main->can("this")' : '! main->can("this")'; eval {print this}; print $@; undef *main::this; # undefine the entire glob print main->can('this') ? 'main->can("this")' : '! main->can("this")'; __END__ # result this main->can("this") Undefined subroutine &main::this called at sub.pl line 7. ! main->can("this")

The first time I try to remove the subroutine via undef it still leaves a CODE slot in the symbol table's *this glob. I can't just use delete because it's not an array or a hash (it fails if you try). This is bad in procedural code but it's awful in OO code because $object->can('this') will succeed even if the method has been deleted.

This leaves me with having to undefine the entire glob but that's a horrible solution because the other slots in the glob, if any, are blown away. Is this a known/documented bug/feature in Perl? Is there a workaround?

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re: Removing subroutines from symbol tables
by chromatic (Archbishop) on Nov 19, 2005 at 07:44 UTC

    I've done this before. I usually end up creating a new glob, with either Symbol's gensym() or my $glob = do { local *GLOB };. Then I copy every slot from the old glob, except CODE of course, into the new glob, then overwrite the old symbol table entry with the new glob.

    I have code somewhere for this; Devel::TraceMethods perhaps. It probably belongs in its own module somewhere.

      It probably belongs in its own module somewhere.

      How about right in Symbol? Seems like the right place for that.

      Makeshifts last the longest.

Re: Removing subroutines from symbol tables
by Aristotle (Chancellor) on Nov 19, 2005 at 07:42 UTC

    That doesn’t surprise me at all. It’s a feature, not a bug: the same behaviour makes sub foo; predeclarations work, as well as things like

    my $x = \&foo; *foo = sub { 'yep' }; print $x->(), "\n"; __END__ yep

    The only solution for what you want that I can think of is to save all the slots from the glob, then blow it away, and finally restore the other slots.

    Makeshifts last the longest.

Re: Removing subroutines from symbol tables
by Steve_p (Priest) on Nov 25, 2005 at 22:00 UTC

    Rather than blasting the entire glob, couldn't you just blast away the CV* inside the glob.

    #!/usr/bin/perl -w use Inline C; use Devel::Peek; sub foo{1;} *{main::Foo} = \&foo; print Dump *Foo; clear_cv(*Foo); print Dump *Foo; __END__ __C__ void clear_cv(SV* gv) { if(SvTYPE(gv) == SVt_PVGV) { GvCV(gv) = Nullcv; } }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://510050]
Approved by sk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (7)
As of 2024-04-18 13:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found