我正在尝试使用包含在字符串中的perl中的sub。
目前我有类似
的东西$sub = "sub{ my $in = shift; if($in =~ /bla.*wam/){return 1;}}";
我尝试使用它
$sub->("test");
或
&{$sub}->("test");
上面的两个例子都只吐出整个函数,好像它是一个它找不到的sub的名字。它看起来像这样:
Undefined subroutine [function then printed here]
我在这里弄错了什么?
答案 0 :(得分:5)
假设标量$sub
包含字符串"foobar"
。如果您说$sub->()
,那么您正在尝试调用名为 foobar
的子例程。如果该子例程不存在,则会出错。
您正在尝试调用名为sub{ my $in = shift; if($in =~ /bla.*wam/){return 1;}}
的子程序,这是一个非常荒谬的子名称,显然在您的程序中不存在。 (实际上,由于它是双引号的,$in
可能在你没有意识到的情况下进行插值。)
所以,首先,不要这样做。
如果你想要一个匿名的子程序,那就这样:
my $sub = sub { my $in = shift; if($in =~ /bla.*wam/) { return 1; } };
然后执行它:$sub->("test");
如果确实需要在字符串中执行代码,那么您可以使用eval
。
my $sub = eval 'sub{ my $in = shift; if($in =~ /bla.*wam/) { return 1; } }';
这将评估字符串中的代码并返回结果,这是一个子引用。在这些字符串来自哪里时要非常小心。制作它们的人可以让你的程序做任何他们想做的事。
答案 1 :(得分:2)
代码和字符串不一样。特别是当你误解了$sub
实际上是什么时。您的codestring是一个双引号字符串。假设$in
的内容为bla wam
,则您将其分配给$sub
:
"sub{ my bla wam = shift; if(bla wam =~ /bla.*wam/){return 1;}}";
这是一个语法错误。
但是,您可以将匿名子例程直接分配给变量:
my $sub = sub{
my $in = shift;
if ($in =~ /bla.*wam/) {
return 1;
}
};
并在示例中调用它(虽然我更喜欢$sub->(...)
样式)。
答案 2 :(得分:1)
删除sub
$sub = sub { my $in = shift; if($in =~ /bla.*wam/){ return 1 } };