2010-12-14 63 views
3

我使用Moose(具体MooseX::Declare)来创建一个迭代器对象,Iter具有next方法,该方法前进状态,并根据需要用于在while语句中使用返回01。我遇到的问题是,根据其中一个构造参数的存在,next需要执行两组完全不同的操作。我看到它的方式我有五个选项:使用Moose时,施工时指定方法体的最佳方式是什么?

  1. 如果...那么next方法
  2. 散列调度
  3. 符号表操纵
  4. 在不同的模块和负载
  5. put方法需要一个在施工时间

只是业余爱好者。

编号2是,我想,是适当的面向对象方式的做事。我没有反对这样做,但似乎有点矫枉过正,只是重写一个单一的方法。

我经常在过程中使用编号3时,它在程序上或伪功能上工作,而这正是我现在所做的。

编号4正如我们都知道的那样,充满了危险,而且我对穆斯胆量在不必要的时候开始乱搞时一无所知。

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

+0

你可能想进一步解释什么不同的行动是迭代器应该执行。不知道完整的用例很难给出设计建议。 – phaylon 2010-12-14 18:52:02

+0

嗯,我真的在寻找一个最佳实践而不是实现细节。我工作得很好,但是哈希调度真的希望我想在'穆斯'范式内做?也就是说,做这件事的'Moosy'方法是什么? – gvkv 2010-12-14 19:01:19

回答

10

通过你的“下一个”子参考到构造函数,并将其保存在一个属性:

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

随着“execute_method”由native attribute 'Code' trait提供的处理程序,您可以拨打“下一个”法作为一个正常的方法它会在属性中找到子参考体。

如果要预先定义的子参考体/ IES,并在施工时决定使用哪个版本,您可以设置的值,根据对象的其他条件的建设者子“下一步”:

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

只是为了让读者明白,没有'is =>'..','reader'或'accessor'是有意的。赋予委托方法与该属性相同的名称非常优雅 - 它以最少的潜在混淆的方式公开了所需的功能。 – hdp 2010-12-15 14:25:14

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); 
} 
相关问题