package Xyzzy; use Exporter; our @ISA=qw(Exporter); our @EXPORT_OK=qw(FullyQualify); use B; use B::Deparse; use Carp; use Devel::FindRef; use Devel::Symdump; use strict; use warnings; #use Smart::Comments; # Given a string or a ref # return its fully qualified name(s) sub FullyQualify { local *coderef=sub { eval { my $obj = B::svref_2object(shift); $obj->GV->STASH->NAME . "::" . $obj->GV->NAME; } || undef; }; #coderef: local *variableref=sub { (my $tmp=(grep {$_->[0] =~ m{^the global}} Devel::FindRef::find($_[0]))[0]->[0]) =~ s{^the global }{}; ### $tmp return $tmp; }; # variableref: unless (ref $_[0]) { # scalar my $name=shift(); my $module; if ($name =~ m{^(.+)::}) { # already qualified $module=Devel::Symdump->new($1); } else { # in this caller $module=Devel::Symdump->new(my $caller=(caller)[0]); $name=$caller.'::'.$name; }; my @return; if (grep {m{^$name$}} $module->functions()) { push(@return,coderef(eval '\&'.$name)) }; if (grep {m{^$name$}} $module->hashes()) { push(@return,variableref(eval '\%'.$name)) }; if (grep {m{^$name$}} $module->arrays()) { push(@return,variableref(eval '\@'.$name)) }; if (grep {m{^$name$}} $module->scalars()) { if (@return) { push(@return,variableref(eval '\$'.$name).'?'); } else { push(@return,variableref(eval '\$'.$name)); }; }; return @return; } else { my $ref=shift; if (ref $ref eq 'CODE') { unless (B::Deparse->new->coderef2text($ref) ne ';') { # $ref is a ref to an autovivified sub Carp::cluck "FullyQualifySubName was passed a coderef to a sub that has been autovivified!"; return undef; }; return coderef($ref); } elsif ((ref $ref) =~ m{^(?:ARRAY|HASH|SCALAR)$}) { return variableref($ref); } else { return "Your ref is a '@{[ref $ref]} ref'!"; }; }; }; __END__