Perl sub由string制成

时间:2013-05-09 20:09:07

标签: perl subroutine

我正在尝试使用包含在字符串中的perl中的sub。

目前我有类似

的东西
$sub = "sub{ my $in = shift; if($in =~ /bla.*wam/){return 1;}}";

我尝试使用它

$sub->("test");

&{$sub}->("test");

上面的两个例子都只吐出整个函数,好像它是一个它找不到的sub的名字。它看起来像这样:

Undefined subroutine [function then printed here]

我在这里弄错了什么?

3 个答案:

答案 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 } };