想象一下这个子程序:
sub test(&&)
{
my $cr1 = shift;
my $cr2 = shift;
$cr1->();
$cr2->();
}
我知道我可以称之为:test(\&sub1,\&sub2)
,但我怎么称它为:
test { print 1 },{ print 2 };
如果我说子程序只需要一个&
,那么发送一个块就行了。我不知道如何使它与2一起工作。
如果我尝试像那样运行它,我得到:
Not enough arguments for main::test at script.pl line 38, near "},"
编辑:没有sub
没有办法调用吗?
答案 0 :(得分:12)
你需要明确说出
test( sub { print 1 }, sub { print 2 } );
或
test { print 1 } sub { print 2 };
隐式“sub”仅适用于第一个参数。 http://perldoc.perl.org/perlsub.html#Prototypes:
An&需要一个匿名子程序,如果作为第一个参数传递,则不需要sub关键字或后续逗号。
有些东西在那里使用额外的词来伪造它:
test { print 1 } against { print 2 };
sub against (&) { $_[0] }
sub test (&@) { ... }
但我从来没有那么喜欢过。
答案 1 :(得分:8)
你可以这样做:
test(sub { print 1 }, sub { print 2 });
答案 2 :(得分:1)
我的一个程序中有以下代码:
sub generate($$$$)
{
my ($paramRef, $waypointCodeRef, $headerRef,
$debugCodeRef) = @_;
...
&$headerRef();
...
my $used = &$waypointCodeRef(\%record);
我用
来称呼它CreateDB::generate(\%param, \&wayPointCode, \&doHeader, \&debugCode);
答案 3 :(得分:1)
如果您真的想更多地弯曲语法,请查看Devel::Declare
使用Devel::Declare
的模块示例:
MooseX::Declare
(GitHub repo)Test::Class::Sugar
(GitHub repo)PerlX::MethodCallWithBlock
(GitHub repo)可以通过modules on CPAN dependant找到关于Devel :: Declare的CPANTS
的完整列表
以下是Test::Class::Sugar pod的示例:
use Test::Class::Sugar;
testclass exercises Person {
# Test::Most has been magically included
startup >> 1 {
use_ok $test->subject;
}
test autonaming {
is ref($test), 'Test::Person';
}
test the naming of parts {
is $test->current_method, 'test_the_naming_of_parts';
}
test multiple assertions >> 2 {
is ref($test), 'Test::Person';
is $test->current_method, 'test_multiple_assertions';
}
}
Test::Class->runtests;
这里有一些性感的PerlX::MethodCallWithBlock pod:
use PerlX::MethodCallWithBlock;
Foo->bar(1, 2, 3) {
say "and a block";
};
与使用像Filter::Simple
这样的源过滤器相比,Devel :: Declare是一种更强大,更健全的扭曲Perl代码的方法。
以下是其作者的video,可能会有所帮助。
/ I3az /