我想在我的班级中将一些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
但是,必须维护角色中的相关方法列表将其与消费类联系起来,这似乎是错误的.我想以更聪明的方式做到这一点,比如方法属性:
package MyApp; use Moose; with (MyApp::Role); sub foo :SomeFlag { ... } sub bar :SomeFlag { ... } sub baz { ... } # this method is unaffected
我不熟悉如何识别方法属性或如何动态地将方法修饰符应用于它们.
或者,也许有更好的方法来做到这一点?
解决方法
让我们使用Attribute :: Handlers – 一种使用属性的相当理智的方法.我们必须在基类中定义一个函数,它本身具有以下属性:ATTR(CODE).这需要一些参数:
>子(或其他变量)来自的包.
>一个globref,或字符串ANON.
>对值的引用(此处为:coderef).
>属性的名称.
>属性的可选数据.
>调用属性的(编译)阶段.
>声明子的文件名.
>声明子的行号.
所以我们可以做的是编写一个应用之前的处理程序:
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/;
我把所有这些都塞进了一个文件中,但这显然不是必要的(只需添加所需的用途).
输出:
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!