1

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

目前我有类似的东西

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

我尝试通过这样做来使用它

$sub->("test");

或者

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

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

Undefined subroutine [function then printed here]

我在这里做错了什么?

4

3 回答 3

5

假设标量$sub包含字符串"foobar"。如果您接着说$sub->(),那么您正试图调用一个名为 foobar的子例程。如果该子例程不存在,您将收到错误消息。

您正在尝试使用 name 调用子例程sub{ my $in = shift; if($in =~ /bla.*wam/){return 1;}},这对于 sub 来说是一个非常荒谬的名称,并且显然在您的程序中不存在。(实际上,由于它是双引号,$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; } }';

这将评估字符串中的代码并返回结果,这是一个子引用。要非常小心这些字符串的来源。制作它们的人可以使您的程序为所欲为。

于 2013-05-09T20:19:53.483 回答
2

代码和字符串不一样。特别是当你有点误解你的$sub实际情况时。您的代码字符串是双引号字符串。假设$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->(...)风格)。

于 2013-05-09T20:17:51.833 回答
1

删除周围的引号sub

$sub = sub { my $in = shift; if($in =~ /bla.*wam/){ return 1 } };
于 2013-05-09T20:15:45.387 回答