Phoenix.pm: has a sub been defined
Beaves at aol.com
Beaves at aol.com
Thu Jan 20 00:46:51 CST 2000
Do yous guys remember a while back when I had the need to determine where a
subroutine was defined or not? We talked a bit about the Perl symbol tables,
etc at one of the PM meetings. Well, can't say if the issue was ever
resolved, but I finally found an easy solution. It was all staring me right
in the face on page 281 of your pew bibles (The Camel Book).
I looked at this code before, but for some reason didn't think that the
statement
'defined &sym' would work because I thought it would run the subroutine.
Well, it doesn't...
I modified it somewhat to also take into account the package from which
&is_sub was called, or to force the package an optional second argument.
sub is_sub {
my $symname = shift;
my $package = shift || ${[caller(0)]}[0];
local *sym = *{"$package\::$symname"};
return 1 if defined &sym
}
### Things can always be improved.
### After thinking about it, I realized I could test for a specific type
sub defined_in_symtable {
my $symname = shift;
my $package = shift || ${[caller(0)]}[0];
my $type = shift || 'CODE'; # why not default to what started this
crap...
local *sym = *{"$package\::$symname"};
if ($type eq 'CODE') { return defined *sym{'CODE'} }
# for some reason, the SCALAR one has to be de-referenced...
elsif ($type eq 'SCALAR') { return defined ${*sym{'SCALAR'}} }
elsif ($type eq 'HASH') { return defined *sym{'HASH'} }
elsif ($type eq 'ARRAY') { return defined *sym{'ARRAY'} }
elsif ($type eq 'FILEHANDLE') { return defined *sym{'FILEHANDLE'} }
}
This code above has not been extensively tested, but initial indications are
that it works as expected.
I hope this may partially demystify Perl symbol tables. I still don't feel
like I know them that well, but I'm constantly adding stuff into my bag o'
experience...
If anyone has any questions about this code, let's get a little discussion
going, and liven things up a little.
Tim
More information about the Phoenix-pm
mailing list