Perl,如何创建一个 map/grep 类的子程序?

Perl, How do I create a map/grep like subroutine?

我想创建一个类似 grep {} @map {} @ 的子程序来处理代码 and/or 布尔输入。不知何故,互联网上没有太多这方面的信息。

我尝试创建下面的子程序,但它甚至无法处理第一个测试。我收到错误 Can't locate object method "BoolTest" via package "input" (perhaps you forgot to load "input"?) at C:\path\to\file.pl line 16..

这怎么认为它是一个对象?我没有正确创建 BoolTest 吗?

# Example senarios
BoolTest { 'input' =~ /test[ ]string/xi };
BoolTest { $_ =~ /test[ ]string/xi } @array;
BoolTest(TRUE);

# Example subroutine
sub BoolTest
{
   if ( ref($_[0]) == 'CODE') {
       my $code = \&{shift @_}; # ensure we have something like CODE
       if ($code->()) { say 'TRUE'; } else { say 'FALSE'; }
   } else {
       if ($_[0]) { say 'TRUE'; } else { say 'FALSE'; }
   }
}

要传递代码引用,您可以使用以下方法:

sub BoolTest { ... }

BoolTest sub { 'input' =~ /test[ ]string/xi };
BoolTest sub { $_ =~ /test[ ]string/xi }, @array;
BoolTest(TRUE);

通过使用 &@ 原型,您可以使 sub 具有与 map BLOCK LIST 相似的语法。

sub BoolTest(&@) { ... }

BoolTest { 'input' =~ /test[ ]string/xi };
BoolTest { $_ =~ /test[ ]string/xi } @array;

这会创建相同的匿名订阅者,因此 returnlast 等将与第一个片段中的行为相同。

请注意,原型版本不接受

BoolTest(TRUE);

除非你重写原型

&BoolTest(TRUE);

但是你不应该期望你的来电者这样做。根据您的示例,您可以让他们使用以下内容,但第二个子项可能更好。

BoolTest { TRUE };