Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl Moose方法修饰符:Call';大约';在'之前;在'之前;和';在'之后;_Perl_Methods_Moose - Fatal编程技术网

Perl Moose方法修饰符:Call';大约';在'之前;在'之前;和';在'之后;

Perl Moose方法修饰符:Call';大约';在'之前;在'之前;和';在'之后;,perl,methods,moose,Perl,Methods,Moose,我正在使用Moose,我需要在我的项目中包装方法调用。我的包装代码必须是最外层的修改器,这一点很重要。到目前为止,我所做的是将我的方法修饰符放在Moose角色中,然后在我的课程结束时应用该角色,如下所示: use Moose::Util; Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole')); __PACKAGE__->meta->make_immutable; CUSTOM RO

我正在使用Moose,我需要在我的项目中包装方法调用。我的包装代码必须是最外层的修改器,这一点很重要。到目前为止,我所做的是将我的方法修饰符放在Moose角色中,然后在我的课程结束时应用该角色,如下所示:

use Moose::Util;
Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole'));
__PACKAGE__->meta->make_immutable;
CUSTOM ROLE before
    CUSTOM ROLE around
        before 2
           before 1
               around
                   method
               around
           after 1
        after 2
    CUSTOM ROLE around
 CUSTOM ROLE AFTER
这使我能够合理地确定我的角色的修饰符是最后定义的,因此为我提供了“before”和“after”的正确行为。(角色中的“before”和“after”分别称为first和first last。)

我原本以为这就足够了,但现在我真的需要用与“around”类似的方式包装方法。构建Moose的Class::MOP首先应用“around”修饰符,因此它们在“before”之后和“after”之前被调用

有关更多详细信息,请参见我的修饰符的当前调用顺序:

CUSTOM ROLE before
    before 2
       before 1
           CUSTOM ROLE around
               around
                   method
               around
           CUSTOM ROLE around
       after 1
    after 2
 CUSTOM ROLE AFTER
我真的需要这样的东西:

use Moose::Util;
Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole'));
__PACKAGE__->meta->make_immutable;
CUSTOM ROLE before
    CUSTOM ROLE around
        before 2
           before 1
               around
                   method
               around
           after 1
        after 2
    CUSTOM ROLE around
 CUSTOM ROLE AFTER

关于如何在我想要的地方应用/调用我的“around”修饰符,有什么想法吗?我知道我可以做一些符号表黑客(比如Class::MOP已经在做了),但我真的不想做。

我对Moose还不太熟悉,但为什么要这样做:

use Moose::Util;
Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole'));
而不仅仅是这个

with 'App:Roles::CustomRole';

关于你的问题,这有点像黑客,但是你能把你的
方法分为
方法,并在你的类定义的末尾应用角色吗(因此它是按你想要的顺序应用的)?如果绝对必要,您可以使用私有属性在两个方法之间保存状态。

最简单的解决方案是让自定义角色定义一个调用主方法的方法,然后将其包装

role MyRole { 
    required 'wrapped_method';
    method custom_role_base_wrapper { $self->wrapped_method(@_) }

    around custom_role_base_wrapper { ... }
    before custom_role_base_wrapper { ... }
}
您遇到的问题是,您正试图让自定义角色包装除方法之外的其他内容。这不是它设计的目的。除了像你建议的那样编写类似的符号表hackery(也许你可以说服一个Moose人在Class::MOP中公开一个API来帮助实现),我能想到的唯一其他解决方案就是上面的一个


如果您不希望
custom\u role\u base\u wrapper
将添加额外的调用堆栈框架,那么您应该查看Yuval或使用
goto
来操作调用堆栈。

问题在于
之前
和之后
都不允许您(干净地)以
前后
的方式更改返回语义。如果这些语义很重要,你就完蛋了。如果不是,为什么要首先使用
around
?我手动应用它的原因是按照定义的顺序添加(然后运行)修饰符。通常,您不关心运行的顺序修饰符。但是,在我的情况下,我希望我的角色的修饰语是最早的,也是最晚的。如果您使用“with”语法来应用角色,那么它的修饰符首先被定义,因此它们将作为最内部的“before”和“after”运行。通过在最后手动应用角色,它们被定义为最后一个,因此在我希望它们运行时运行。@Matt:这似乎确实是Moose的一个缺点。也许
after
语义应该允许改变返回值,就像
around
那样,或者应该修改
before
方法、
around
方法和
after
方法的顺序,使它们都是相对于彼此的后进先出,而不仅仅是相对于它们自己的后进先出(如果有意义的话).before
和before
是专门设计的,不包含这样的副作用。具体来说,
之前的
之后的
应该用于附加到方法的带外行为,而
周围的
仅用于这种方法“覆盖”。像这样改变三年前的语义学真的不是驼鹿团队会接受的,我也不认为这是真正的答案。我同意以太下面的问题,为什么要使用
Moose::Util::apply_all_roles
而不是
with
?我希望我的角色中的“before”和“after”修饰符与类中可能已经存在的其他修饰符相比,能够最先或最后运行。稍后手动应用角色定义修饰符,然后首先运行修饰符(用于之前),最后运行修饰符(用于之后)。@perigrin我终于理解了你和以太的问题。我不需要像我想的那样,把这个角色应用到所有的角色上。我对Moose还是一个新手,一直在考虑是否需要“手动”应用角色。我真正需要做的是在文件末尾(在其他修改器之后)使用“with”来应用角色,而不是在文件开头。我最终采用了自定义包装器的想法。它给了我所需要的灵活性,谢谢。