4

我在使用 eval 函数时遇到问题。

事实上,我在 SQL 数据库中有一些函数名,我的目标是在 perl 中执行这些函数(在 SQL 中检索之后)。

考虑到 $RssSource->{$k}{Proceed} 包含“&test”作为从 SQL 检索的字符串,这就是我正在做的事情:

my $str2 = "ABCD";
eval "$RssSource->{$k}{Proceed}";warn if $@;

sub test
{
   my $arg = shift;

   print "fct TEST -> ", $row, "\n";
}

这工作正常并显示:

fct TEST ->

但是我希望能够将 $str2 作为参数传递给 $RssSource->{$k}{Proceed} 但我不知道如何,我尝试的每个语法都返回一个错误:

eval "$RssSource->{$k}{Proceed}$str2"
eval "$RssSource->{$k}{Proceed}($str2)"
eval "$RssSource->{$k}{Proceed}"$str2
eval "$RssSource->{$k}{Proceed}"($str2)

有人可以告诉我如何正确地将参数传递给评估函数吗?

非常感谢你的帮助

问候。

弗洛朗

4

5 回答 5

5

我将假设$RssSource->{$k}{Proceed}始终包含nameor &name,否则您的要求没有多大意义。

my $func_name = $RssSource->{$k}{Proceed};
$func_name =~ s/&//;
my $func_ref = \&$func_name;    # Works with strict on!
$func_ref->(@args);

如果要添加一些错误检查,以下将检查是否可以调用 sub:

defined(&$func_ref)
于 2012-10-03T22:21:22.827 回答
3

如果您正在使用的字符串eval始终是子调用,则可以通过以下方式之一构造 eval 字符串:

$RssSource->{$k}{Proceed} . '($str2)'

(最一般的),或

$RssSource->{$k}{Proceed} . "(\"$str2\")"

(不雅)

以下是您的解决方案遇到的问题:

eval "$RssSource->{$k}{Proceed}$str2"评估为eval "&testABCD"。这个子不存在。

eval "$RssSource->{$k}{Proceed}($str2)"评估为"&test(ABCD)"。不允许裸词。

eval "$RssSource->{$k}{Proceed}"$str2字符串后面必须跟某种运算符,而不是另一个变量。

eval "$RssSource->{$k}{Proceed}"($str2)您正在尝试将字符串作为函数调用。Perl 不支持此功能。

于 2012-10-03T21:33:16.280 回答
2

如果您可以将数据库中的数据更改为只包含一个函数名,也就是说,test而不是&test,您可以通过符号引用而不是使用 eval 来调用函数:

$fn="test";
&{$fn}("argument")
于 2012-10-03T21:35:26.220 回答
1

如您所说,如果您的数据库仅包含函数名称,则不需要 eval 。您可以将它们用作符号引用(但请删除 &)。这样做的现代方法不是使用 & 来取消引用它,而是使用箭头运算符:

{
    no strict 'refs'; # hopefully you have strict on already...
    $RssSource->{$k}{Proceed}->($str2);
}
于 2012-10-03T23:23:20.610 回答
0

很像ikegami的回答,用的can方法,比较符合我的口味。蒂姆托迪。

my $func_name = $RssSource->{$k}{Proceed};
$func_name =~ s/&//;
my $func_ref = __PACKAGE__->can($func_name)
  or die "No function named $func_name";
$func_ref->(@args);
于 2012-10-04T02:13:03.500 回答