print grep /test/, "mytestphrase";
使用grep语法,您可以传入一个没有引号的正则表达式。 我希望我的子程序具有相同的行为,如下所示:
use strict;
use warnings;
sub testsub {
my $regex = shift;
my $phrase = shift;
print grep $regex, $phrase;
}
testsub /test/, "mytestphrase";
然而,它在testsub调用之前尝试对我的正则表达式进行评估$_
,发出以下错误:
Use of uninitialized value $_ in pattern match (m//) at ./a.pl line 14.
是否可以像grep命令一样调用testsub以及如何修改子例程以支持它?
答案 0 :(得分:4)
传递如下参数:
testsub qr/test/, "mytestphrase";
还将$regex
的使用率更改为/$regex/
:
#!/usr/bin/perl
use strict;
use warnings;
sub testsub {
my $regex = shift;
my $phrase = shift;
print grep /$regex/, $phrase;
}
testsub qr/test/, "mytestphrase";
答案 1 :(得分:2)
AFAIK没有办法复制grep的特殊“拿一个块或采取一个裸表达式”的语法。 As pointed out in TLP's answer,您可以使用&@
原型获取foo {...} LIST
语法,但不能要求块或标量。
也没有原型来获得简单的正则表达式。您必须传入已编译的正则表达式qr/.../
,as noted by M42。
原型不完整。它们无法表达Perl内置函数的全部功能。 open
,split
,print
,甚至是chomp
等显然简单的print prototype 'CORE::some_function'
。您可以通过询问&@
来查看此内容。有人说这是原型的弱点。有人说这是Perl内置功能的疯狂。
只有在替换内置函数时才应使用原型。他们真的是最好的避免。少数有效成语之一是使用foo {...} LIST
原型为列表处理提供qr//
成语。
我建议您将sub { ... }
或grep
正常传递给您的函数并将其传递给qr//
。
我是否说无法这样做?我在想什么,这是Perl!如果你真的真的想要这个功能,你可以深入研究Devel::Declare。此模块允许您提供自己的函数调用语法。说它不容易使用是轻描淡写。 Method::Signatures和TryCatch之类的东西用它来发挥他们的魔力。如果您只是在计算{{1}},我建议不要将Devel :: Declare放入生产代码中。尽管如此,还是把它搞乱了。
答案 2 :(得分:1)
如果你阅读http://perldoc.perl.org/perlsub.html#Prototypes,你会发现这个例子:
Declared as Called as
...
sub mygrep (&@) mygrep { /foo/ } $a, $b, $c
你可能指的是什么。
大多数情况下,原型并不是您想要的,不应该使用。原型用于使Perl子例程像某些内置函数一样工作,例如grep
。
至于建议,我建议你按照his answer中的M42建议做。