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

gvk*_*vkv 3 perl moose

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

  1. 如果...然后在next方法中
  2. 子类
  3. 哈希调度
  4. 符号表操作
  5. 将方法放在不同的模块中,并在施工时加载所需的一个

1号只是业余爱好者.

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

我过去常常在程序上或伪功能上使用3号,这就是我现在正在做的事情.

4号是,大家都知道,充满了危险,我一无所知穆斯胆量要开始瞎搞不必要的时候.

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

Eth*_*her 10

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

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

使用本机属性"Code"特征提供的"execute_method"处理程序,您可以将"next"方法作为普通方法调用,它将在属性中找到subref主体.

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

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

  • 只是为了让任何人都能明白这一点,事实上没有`is =>'..'`,`reader`或`accessor`是故意的.赋予方法与属性相同的名称非常优雅 - 它可以准确地暴露所需的功能,同时最大限度地减少潜在的混淆. (3认同)