2010-06-16 124 views
2

處理彼此使用的模塊的最佳方式是什麼?處理彼此使用模塊的最佳方式是什麼?

比方說,我有這對於哈希函數模塊:已分割出的名單

# Really::Useful::Functions::On::Hash.pm 

use base qw<Exporter>; 
use strict; 
use warnings; 

use Really::Useful::Functions::On::List qw<transform_list>; 

our @EXPORT_OK = qw<transform_hash transform_hash_as_list ...>; 

#... 
sub transform_hash { ... } 

#... 
sub transform_hash_as_list { 
    return transform_list(%{ shift() }); 
} 
#... 
1 

而另一個模塊:

# Really::Useful::Functions::On::List.pm 

use base qw<Exporter>; 
use strict; 
use warnings; 

use Really::Useful::Functions::On::Hash qw<transform_hash>; 

our @EXPORT_OK = qw<transform_list some_func ...>; 

#... 
sub transform_list { ... } 

#... 
sub some_func { 
    my %params = transform_hash @_; 
    #... 
} 

#... 
1 

假設足夠的這些實用功能足夠方便我希望在BEGIN語句和導入函數中使用它們來處理參數列表或配置數據。

我一直在將子定義放入BEGIN塊以確保它們隨時可以使用,只要有人包含該模塊。但是我已經進入了毛病的比賽條件,在BEGIN塊中沒有完成定義。

我將不斷演變的代碼習慣用法放入模塊中,以便我可以重複使用任何習慣用法,我發現自己一次又一次地編碼。例如:

sub list_if { 
    my $condition = shift; 
    return unless $condition; 
    my $more_args = scalar @_; 
    my $arg_list = @_ > 1 ? \@_ : @_ ? shift : $condition; 
    if ((reftype($arg_list) || '') eq 'ARRAY') { 
     return wantarray ? @$arg_list : $arg_list; 
    } 
    elsif ($more_args) { 
     return $arg_list; 
    } 
    return; 
} 

捕捉這兩種習慣用法,我是有點累打字:

@{ func_I_hope_returns_a_listref() || [] } 

($condition ? LIST :()) 

我越在定義函數BEGIN塊,越有可能我將使用這些成語磚來表達邏輯,BEGIN塊中需要更多磚塊。

人們是否有處理這種語言成語磚模型的標準方法?

我一直在做的主要是Pure-Perl; XS是否會緩解一些呢?

+2

替補在編譯時被加載,無論它們是否在BEGIN塊。你可以展示一個你需要在BEGIN塊中定義的函數的例子嗎? – mob 2010-06-16 15:58:19

+0

@mobrule:或許我不需要把它們放在BEGIN塊中,但這就是工作,使用修補程序,直到你沒有一個「解決」問題的錯誤方法。當我試圖積累越來越多的這些成語磚以逐步提高編碼和測試的速度時,哪種激勵了長期存在的問題。 – Axeman 2010-06-16 16:16:19

回答

2

如果兩個模塊是相互依賴的,那麼設計就會出現問題。如果我是你,我會考慮重構我的模塊。

+0

這是一種可能性,但這些並不是真正的「設計」元素,但或多或​​少是代碼習語的集合,這些習語本身在其他代碼習語中很有用。 – Axeman 2010-06-16 16:34:24

2

您可以擁有兩個模塊,每個模塊都可以調用另一個模塊,因爲這些調用是在運行時完成的,然後「所有」都將被加載。但是,(顯然)這意味着您需要進入運行階段而不會被炸掉。一種常用的方法是將其他模塊包含在內,比這兩個模塊中的任何一個都早,包括use。直接刪除直接use語句的結果是,您將失去這些導入,但是將符號從一個模塊導入另一個模塊並不是一個好主意。

看着你寫的代碼,我感到非常驚訝,你已經想出了許多處理數據的「新」方法,你覺得需要將這些數據提取到不同的庫中。你看過標準庫Hash::Util,List::UtilList::MoreUtils嗎?我建議你使用標準庫,以更習慣的Perlish方式退出你的庫和代碼。

+0

'List :: Util'和'List :: MoreUtils'肯定存在,但'Hash :: Util'作爲散列的一般實用程序庫幾乎沒有用處,除非您的問題是鎖定鍵和其他一些處理哈希的硬結構,而不是它們作爲通用實現的一般抽象:名稱 - 值協會。具有諷刺意味的是,我想在CPAN上放置一個廣義的散列實用程序,這部分激發了我對我的「解決方案」的擔憂。 AFAIK,對於* OO *模塊,進口主要是一個壞主意,因爲它們會給出關於類能力和推斷行爲的誤報。 – Axeman 2010-06-16 16:32:03

5

如果你想擁有相互依賴的模塊,一個簡單的方法來完成這項工作是使用具有完全限定名稱的後期綁定子例程調用(換句話說,在子調用中使用parens)。原型不會工作,但Perl不會在意Somepackage::mysub()沒有定義,直到你真的試圖調用它。當我編寫相互依賴的模塊時,我通常將它們保存在同一個文件中,通過完全避免導入來簡化情況。

而且,沒有必要在一個BEGIN塊來定義自sub name {...}子相同BEGIN {*name = sub {...}}

相關問題