我希望能够从 Perl eval 捕获变量赋值。也就是说,确定代码中分配给哪些变量名称并提取它们的值。
例如,如果我运行:
eval '$foo=42; $bar=3.14;'
eval 的结果是 3.14(最后评估的值),但我还希望能够确定名称“$foo”和“$bar”及其值(无需提前知道名称)。
我已经阅读了通过 Safe 和 Eval::Context 将变量插入 eval 块的几种方法,但还没有任何提取它们的方法。我更熟悉Python的eval/exec,它们内置了对此的支持。
在 eval 中声明的任何词法变量都将在 eval 结束后丢失。要捕获和隔离 eval 中设置的全局变量,您可以考虑使用Safe http://perldoc.perl.org/Safe.html#reval-%28STRING,-STRICT%29模块创建一个新的全局命名空间。像下面这样:
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
功能。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)