after foo => sub{
...
}
我只是偶然发现了上面的代码,这些代码在sub foo
完成后调用,
这是如何运作的?
似乎它不是Perl的内置功能,对吗?
答案 0 :(得分:5)
方法修饰符可用于向方法添加行为,而无需修改这些方法的定义。
答案 1 :(得分:3)
出于好奇,我试图自己做,并获得在某种程度上有效的代码(没有列表上下文,没有角落案例等)。
Perl允许可怕的事情。
% perl -wle 'use After; sub foo { $_[0] * 2};
after foo => sub { print $_[0] }; foo(5); foo(6);'
10
12
这是After.pm。请不要 使用它。
use warnings;
use strict;
package After;
# make after() available after 'use After;'
use Exporter;
BEGIN {
our @ISA = qw(Exporter);
our @EXPORT = qw(after);
};
# prototype: bareword + sub
sub after (*&) {
my ($name, $code) = @_;
my $caller = caller; # get calling package
# fetch old sub named "name"
# note $oldcode = *{...} is not ehough
my $oldcode;
{
no strict 'refs';
$oldcode = \&{$caller."::".$name};
};
# defined new sub
my $newcode = sub {
my $ret = $oldcode->(@_); # call old sub as is
$code->($ret); # call the after sub
return $ret; # ignore aftersub's ret val
};
# plant new sub into the calling package
# avoid redefinition warnings
{
no strict 'refs';
no warnings 'redefine';
*{$caller."::".$name} = $newcode;
};
};
1;
答案 2 :(得分:3)
这不是其他人已经说过的内置功能。对于不使用Moose
的程序,您可以使用Class::Method::Modifiers
来获取这些修饰符。
答案 3 :(得分:1)
如果after
是预先声明的子例程,则意味着您使用foo
和匿名子作为参数调用该子。但这确实有点奇怪。
=>
相当于一个逗号,因此假设after
是一个sub,则意味着:
after('foo', sub { ... });