我想在我的班级中将一些Moose'adfore'方法修饰符应用于许多方法.我想在角色中提供修饰符方法.我可以这样做:
package MyApp::Role;
use Moose::Role
before [qw(foo bar)] => sub {
...
};
package MyApp;
use Moose;
with (MyApp::Role);
sub foo { ... }
sub bar { ... }
sub baz { ... } # this method is unaffected
Run Code Online (Sandbox Code Playgroud)
但是,必须维护角色中的相关方法列表将其与消费类联系起来,这似乎是错误的.我想以更聪明的方式做到这一点,比如方法属性:
package MyApp;
use Moose;
with (MyApp::Role);
sub foo :SomeFlag { ... }
sub bar :SomeFlag { ... }
sub baz { ... } # this method is unaffected
Run Code Online (Sandbox Code Playgroud)
我不熟悉如何识别方法属性或如何动态地将方法修饰符应用于它们.
或者,也许有更好的方法来做到这一点?
让我们使用Attribute::Handlers它 - 一种使用属性的相当理智的方法.我们必须在基类中定义一个本身具有该属性的函数:ATTR(CODE).这需要一些参数:
ANON.所以我们可以做的是编写一个应用before:
use strict; use warnings; use feature 'say';
BEGIN {
package MyRole;
use Moose::Role;
use Attribute::Handlers;
sub SomeFlag :ATTR(CODE) {
my ($package, $globref, $code, $attr, $data, $phase, $filename, $line) = @_;
ref($globref) eq 'GLOB'
or die "Only global subroutines can be decorated with :SomeFlag"
. " at $filename line $line.\n";
# use the MOP to install the method modifier
$package->meta->add_before_method_modifier(
*$globref{NAME} => sub {
warn "Just about to call a flagged sub!";
},
);
}
}
BEGIN {
package MyApp;
use Moose;
# important: SomeFlag must be available before the attrs are handled (CHECK phase)
BEGIN { with 'MyRole' };
sub foo :SomeFlag { say "Hi from foo sub!" }
sub bar :SomeFlag { say "Hi from bar sub!" }
sub baz { say "Hi from baz sub!" }
}
package main;
my $o = MyApp->new;
$o->$_ for qw/foo bar baz/;
Run Code Online (Sandbox Code Playgroud)
我把所有这些都塞进了一个文件中,但这显然不是必要的(只需添加所需的uses).
输出:
Just about to call a flagged sub! at so.pl line 16.
Hi from foo sub!
Just about to call a flagged sub! at so.pl line 16.
Hi from bar sub!
Hi from baz sub!
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
125 次 |
| 最近记录: |