使用原型,您可以创建一个子程序,接受一段代码作为其第一个参数:
sub example (&) {
my $code_ref = shift;
$code_ref->();
}
example { print "Hello\n" };
我怎么能做同样的事情,但有多个代码块?我想使用代码块,而不是变量或sub { ... }
。
这不起作用:
sub example2 (&&) {
my $code_ref = shift;
my $code_ref2 = shift;
$code_ref->();
$code_ref2->();
}
example2 { print "One\n" } { print "Hello\n" };
它给出了这个错误:
Not enough arguments for main::example2
答案 0 :(得分:9)
我希望您意识到这只是代码调节,而您所实现的只是一种更整洁的语法而牺牲了清晰度?
Perl不允许您将多个裸块传递给子例程,但第二个实际参数可能是对子例程的调用,该子例程也占用一个块并简单地返回代码引用。
该程序演示。请注意,我已选择please
和also
作为子例程的名称。但是你必须使用适合你自己的代码功能的东西,并且不太可能与即将到来的核心语言扩展冲突。
use strict;
use warnings;
sub please(&$) {
my ($code1, $code2) = @_;
$code1->();
$code2->();
}
sub also(&) {
$_[0];
}
please { print "aaa\n" } also { print "bbb\n" };
<强>输出强>
aaa
bbb
答案 1 :(得分:1)
适合我...
sub example2 {
my $code_ref = shift;
my $code_ref2 = shift;
$code_ref->();
$code_ref2->();
}
example2 ( sub { print "One\n" }, sub { print "Hello\n" });
仅仅为了TMTOWTDI的目的,这里的方法有点像OP请求的方式
首先,制作一个源过滤器
package poop;
use Filter::Util::Call;
sub import {
my ($type) = @_;
my ($ref) = [];
filter_add( bless $ref );
}
sub filter {
my ($self) = @_;
my ($status);
if (( $status = filter_read() ) > 0) {
if(!/sub/ && /example2/) {
s/\{/sub \{/g;
}
}
$status;
}
1;
其次必须使用过滤器
use poop;
sub example2 {
my $code_ref = shift;
my $code_ref2 = shift;
$code_ref->();
$code_ref2->();
}
example2 ( { print "One\n" }, { print "Hello\n" });
PS。这是可怕的,没有人希望看到这实际上在生产
答案 2 :(得分:1)
你试过在两个街区之间插一个逗号吗?
You have: example { print "One\n" } { print "Hello\n" };
You probably want: example { print "One\n" }, { print "Hello\n" };
我错了......
但这对我有用:
example { print "One\n" } sub { print "Hello\n" };
答案 3 :(得分:0)
你可以eval
块
use experimental 'signatures';
use feature 'say';
sub doublethecode ($block1, $block2) { eval { $block1; }; eval { $block2;} } ;
doublethecode \&{ print "OH " }, \&{ say for qw/HAI YOU LOLCAT :-P/ };
<强>输出强>:
OH, HAI
YOU
LOLCAT
:-P
然后忽略\&
,你就在那里。
从v5.20
开始,您可以同时使用签名和:prototype
属性。 signatures
功能提供了更“通用”的语法和极简主义的参数检查。也许有一天,未来的perl会有一个“内置”(可选的,高度灵活的)类型系统,但是现在原型并不是那样的。如下所示:
sub doublethecode :prototype(\&\&) ($cr1, $cr2) { $cr1 ; $cr2 ; }
不是它看起来的样子。由于原型,signatures
和:prototype(&&)
签名可能无法提供您的想法,这可能已经足够了:
sub doublethecode { eval { shift }; eval{ shift } } ;
doublethecode &{ print "perl" }, &{ print "6" }
<强>输出强>:
perl6
为确保perl不认为{}
是哈希值,&
是必需的。但实际上......在这里使用匿名子程序sub { }
是 是错误的吗?
答案 4 :(得分:0)
Fwiw,在Perl 6中:
sub doublecode (&foo, &bar) { foo(), bar() }
doublecode { print 1 }, { print 2 } # prints 12