2010-12-14 64 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); 
} 
相關問題