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;
这会创建相同的匿名订阅者,因此 return
、last
等将与第一个片段中的行为相同。
请注意,原型版本不接受
BoolTest(TRUE);
除非你重写原型
&BoolTest(TRUE);
但是你不应该期望你的来电者这样做。根据您的示例,您可以让他们使用以下内容,但第二个子项可能更好。
BoolTest { TRUE };
我想创建一个类似 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;
这会创建相同的匿名订阅者,因此 return
、last
等将与第一个片段中的行为相同。
请注意,原型版本不接受
BoolTest(TRUE);
除非你重写原型
&BoolTest(TRUE);
但是你不应该期望你的来电者这样做。根据您的示例,您可以让他们使用以下内容,但第二个子项可能更好。
BoolTest { TRUE };