加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl – 如何将Moose方法修饰符应用于基于方法属性的方法?

发布时间:2020-12-16 06:17:48 所属栏目:大数据 来源:网络整理
导读:我想在我的班级中将一些Moose’adfore’方法修饰符应用于许多方法.我想在角色中提供修饰符方法.我可以这样做: package MyApp::Role;use Moose::Rolebefore [qw(foo bar)] = sub { ...};package MyApp;use Moose;with (MyApp::Role);sub foo { ... }sub bar
我想在我的班级中将一些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!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读