Вы могли бы искать либо ключи, заканчивающиеся на '::', которые указывали бы, что у него есть другие пакеты, либо все значения являются символьными ссылками.
- Конечно, даже здесь это будетТрудно отличить тайник от хэша, который просто хранит символы (по какой-либо причине).Я копался с
B::svref_2object
, но даже символы из тайника, хранящегося в обычном хеше, возвращали бы что-то за $sym->can( 'STASH' )
.
Я думаю, что вы могли бы сделать это спуститься через таблицу символови посмотреть, если тайник указывает на ту же самую область памяти.
Примерно так:
use Scalar::Util qw<refaddr>;
my %seen;
sub _descend_symtable {
$calls++;
my ( $cand, $stash_name ) = @_;
my $stash = do { no strict 'refs'; \%{ $stash_name }; };
return if $seen{ refaddr( $stash ) }++;
return $stash_name if $cand == $stash;
my $result;
foreach my $s ( grep { m/::$/ } keys %$stash ) {
$result = _descend_symtable( $cand, "$stash_name$s" )
and return $result;
}
return;
}
sub find_in_symtable {
my $needle = shift;
%seen = ();
return _descend_symtable( $needle, 'main::' );
}
Спектакль не был ужасен .