Любые лексические переменные, объявленные в eval, будут потеряны после его окончания.Чтобы захватить и изолировать глобальные переменные, которые установлены в eval, вы можете использовать модуль Safe для создания нового глобального пространства имен.Что-то вроде следующего:
use Safe;
my $vars = Safe->new->reval(qq{
$code_to_eval;
$code_to_search_the_symbol_table_for_declared_variables
});
Где код поиска определяется как нечто, обходящее вложенную таблицу символов %main::
, ищущую любые переменные, представляющие интерес.Вы можете сделать так, чтобы он возвращал структуру данных, содержащую информацию, и затем вы можете делать с ней то, что вам нравится.
Если вы беспокоитесь только о переменных, определенных на корневом уровне, вы можете написать что-то вроде:
use strict;
use warnings;
my $eval_code = '$foo=42; $bar=3.14;';
use Safe;
my $vars = Safe->new->reval(
$eval_code . q{;
my %vars;
for my $name (keys %main::) {
next if $name =~ /::$/ # exclude packages
or not $name =~ /[a-z]/; # and names without lc letters
my $glob = $main::{$name};
for (qw($SCALAR @ARRAY %HASH)) {
my ($sigil, $type) = /(.)(.+)/;
if (my $ref = *$glob{$type}) {
$vars{$sigil.$name} = /\$/ ? $$ref : $ref
}
}
}
\%vars
});
print "$_: $$vars{$_}\n" for keys %$vars;
# $foo: 42
# $bar: 3.14
В поисковом коде также может использоваться Padwalker для поиска в текущей лексической области любых заданных переменных с использованием функции peek_my
.