Selective deletion from symbol table?

J

J Krugman

Suppose I have this:

*foo = sub { print "hello from foo\n" };
*foo = \3;

Now &foo and $foo are defined in the current package (let's say
it's main). Now suppose that I want to undefine &foo. Something
like

delete $main::{foo}

would undefine not only &foo but $foo as well. Is there a way to
undefine *only* &foo?

Thanks!

jill

P.S. The motivation for this question is the sub mk_classdata, the
sole method in the CPAN module Class::Data::Inheritable:

sub mk_classdata {
my ($declaredclass, $attribute, $data) = @_;

my $accessor = sub {
my $wantclass = ref($_[0]) || $_[0];

return $wantclass->mk_classdata($attribute)->(@_)
if @_>1 && $wantclass ne $declaredclass;

$data = $_[1] if @_>1;
return $data;
};

my $alias = "_${attribute}_accessor";
*{$declaredclass.'::'.$attribute} = $accessor;
*{$declaredclass.'::'.$alias} = $accessor;
}

This is nice, but IMHO one *minor* flaw is that once one makes a
derived class "opaque" with respect to a given class attribute
(which happens if one sets the class attribute for the derived
class $wantclass) there is no way to undo this. It would be nice
if, for example, setting the class attribute for the derived class
to undef had the effect of making the derived class once again
"transparent" with respect to the class attribute. Or course, this
is not perfect either, since there may be cases in which undef is
a perfectly acceptable value for the class attribute to have, and
in these cases we wouldn't want this behavior, but, in any case,
it got me thinking about the general problem of selectively undoing
an assignment such as

*{$declaredclass.'::'.$attribute} = $accessor;
 
S

Steven Kuo

Suppose I have this:

*foo = sub { print "hello from foo\n" };
*foo = \3;

Now &foo and $foo are defined in the current package (let's say
it's main). Now suppose that I want to undefine &foo. Something
like

delete $main::{foo}

would undefine not only &foo but $foo as well. Is there a way to
undefine *only* &foo?
...




Use 'undef' as described in 'perldoc perlsub':

use strict;
use warnings;
use vars qw(*foo);

*foo = sub { print "hello from foo\n" };
*foo = \3;

foo();
print $foo, "\n";

undef(&{*foo{CODE}}); # see 'perldoc perlref' regarding this syntax

# or more simply:
# undef(&foo);

eval {
foo();
};

print "Uable to run foo subroutine : $@";

print $foo, "\n";
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top