使用Moose时,在施工时分配方法体的最佳方法是什么?

时间:2010-12-14 18:07:28

标签: perl moose

我正在使用Moose(特别是MooseX::Declare)创建一个迭代器对象Iter,该对象具有一个next方法,可以提升状态并返回01根据while声明的要求使用。我遇到的问题是,根据其中一个构造参数的存在,next需要执行两组非常不同的操作。我看到它的方式我有五个选择:

  1. if ...然后在next方法
  2. 子类
  3. 哈希调度
  4. 符号表操作
  5. 将方法放在不同的模块中,并在施工时加载所需的一个
  6. 1号只是业余爱好者。

    我认为

    2号是正确的OOP做事方式。我不反对这样做,但似乎有点矫枉过正,只是覆盖一个方法。

    我过去经常使用 3号进行程序性或伪功能性处理,而这正是我现在正在做的事情。

    众所周知,

    4号充满了危险,我对Moose Guts一无所知,希望在不必要的时候开始搞乱。

    最后一项, 5号在我看来是最明智的(和Per​​lish)但是像2号一样,有点太多了。我真的很想知道是否有第五种方法我没有考虑过如同挂钩到元类,或者是一个相当成熟的MooseX模块。

2 个答案:

答案 0 :(得分:10)

将“next”subref传递给构造函数并将其保存在属性中:

has next => (
    isa => 'CodeRef',
    required => 1,
    traits => ['Code'],
    handles => { next => 'execute_method' },
);

使用native attribute 'Code' trait提供的'execute_method'处理程序,您可以将'next'方法作为普通方法调用,它将在属性中找到subref主体。

如果要预先定义subref主体并在构造时确定要使用的版本,可以根据对象的其他条件在构建器子中设置“next”的值:

has next => (
    # ...
    lazy => 1,
    default => sub {
         my $self = shift;
         return sub { ... } if $self->some_condition;
         # etc etc...
    },
);

答案 1 :(得分:0)

另一种选择是动态应用角色:

package Iter;
use Moose;
use Moose::Util qw(apply_all_roles);

has next_role => (is => 'ro');

sub BUILD {
    my $self = shift;
    apply_all_roles($self, $self->next_role);
}