【问题标题】:Why doesn't Moose role application with method modifiers work in my code?为什么带有方法修饰符的 Moose 角色应用程序在我的代码中不起作用?
【发布时间】:2011-01-17 03:24:21
【问题描述】:

我有一个角色和几个混合角色的类。 Role 类加载所有实现类,以便导入 Blah 的任何内容都可以使用它们,而无需输入大量“使用”行。

package Blah;
use Moose::Role;

use Blah::A;
use Blah::B;
(etc...)

requires '...';
requires 'foo';
around 'foo' => sub { ... }

一个典型的 Blah 子类:

package Blah::A;
use Moose;
with 'Blah';

sub foo { ... }

__PACKAGE__->meta->make_immutable;

由于每个子类 'foo' 方法都以相同的代码位开始,因此角色也通过方法修饰符实现这些。

问题是:Moose 没有将方法修饰符应用于任何 Blah::* 类。即使我删除了类的 make_immutable 调用,也会发生这种情况。我认为角色应用完全是在运行时完成的,所以即使在 Blah 之前加载了 Blah::* 类,仍然应该应用修饰符?

我正在寻找解决方法,或另一种做事方式。目前 Blah 本质上是一个抽象基类,除了方法修饰符,这就是我使用角色开始的原因 - 但也许类层次结构会更好?提前致谢。

【问题讨论】:

    标签: perl moose role method-modifier


    【解决方案1】:

    你的调用顺序有点奇怪——为什么你 useing Blah::A 来自然后应用于 Blah::A 的角色?

    我建议拉出这些use 行并将它们移动到实际需要它们的位置(在调用者中)。先让代码工作起来,然后,如果你有很多 use 行,到处乱七八糟,你可以把它们移到包含文件中。

    但是不,作为对您的假设的回答——角色应用程序不是在运行时完成,而是在遇到with 行的任何时间完成。如果您在编译时 use 一个模块,则该文件将立即编译,并执行 with 行(然后强制编译该角色,然后运行)。当然,您也可以在运行时应用角色(例如,请参阅 Moose::Util 中的 apply_all_roles),但这不是这里发生的事情。

    【讨论】:

    • 已接受,谢谢。使用行很烦人,但我想我会为它们编写一个工厂模块,而不是重载角色模块:)
    • @rjh:是的,你只是在角色有机会完成自身构建并应用到它们之前太快地加载这些目标模块。
    【解决方案2】:

    我认为您只是误解了文件包含和角色组成之间的区别。

    在底层,use 语句只需调用 require,然后是推断的 Package 的 import() 语句,并将所有这些包装在一个 BEGIN {} 块中。

    它不会将函数安装为具有 Class::MOP (CMOP) 的元类方法。我不确定声明的方法和导入的方法之间有什么区别,或者 CMOP 如何区分差异,但这只是因为调用了add_method。我想从 irc.perl.org/#moose 获得更多信息,但我被禁止了。希望这个例子能告诉你你需要什么,或者给你更多的信息来制定一个更好的问题。

    package Class;
    use Moose;
    use Carp qw(carp);
    
    ### You have to add the method onto the class.
    Class->meta->add_method( 'carp' => \&carp );
    
    around 'carp' => sub { warn "this won't trigger" };
    
    package main;
    
    my $c = Class->new;
    $c->carp('foo');
    

    如果可能的话,我会将您的 useing 的那些包重写为 Moose 友好角色,然后让当前角色使用 with 语句调用新角色。角色将处理围绕其他角色提供的方法的方法修饰符。

    【讨论】:

    • Evan 我认为您完全错过了这里的问题。他正在使用角色(Blah 是 Moose::Role)。他的问题与循环使用语句有关(使用执行您当前定义的角色的类是不好的 M'kay?)和时间(当看到 with 时会发生以太指出的组合,并且可以导致问题)。我看不出您的示例与该问题有什么关系,因为他既没有使用导入,也没有显示像您在此处所做的那样使用 around 修饰符完全覆盖方法的示例。 Rjh 可以免费进入#moose 了解更多信息。
    • 继续讨论,我将假设问题是 特定于use 案例,因为该代码在没有它的情况下也可以工作(删除使用和要求)实例化Blah::A,我相信“周围”会起作用。也许我试图推断很多。
    猜你喜欢
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-02
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多