2011-01-10 78 views
3

因此,在經歷了一段令人尷尬的時間調試之後,我終於將this issue簡化爲一個簡單的測試用例。我會虛心請求一些幫助,理解它失敗的原因。 :)以下是錯誤消息我得到:MooseX ::類型聲明問題,嚴格測試用例:)

plxc16479> $h2/tmp/tmp18.pl 
This method [new] requires a single argument. at /nfs/pdx/disks/nehalem.pde.077/perl/5.12.2/lib64/site_perl/MooseX/Types/TypeDecorator.pm line 91 

MooseX::Types::TypeDecorator::new('MooseX::Types::TypeDecorator=HASH(0x655b90)') called at /nfs/pdx/disks/nehalem.pde.077/projects/lib/Program-Plist-Pl/lib/Program/Plist/Pl.pm line 10 

Program::Plist::Pl::BUILD('Program::Plist::Pl=HASH(0x63d478)', 'HASH(0x63d220)') called at generated method (unknown origin) line 29 

Program::Plist::Pl::new('Program::Plist::Pl') called at /nfs/pdx/disks/nehalem.pde.077/tmp/tmp18.pl line 10 

封裝測試腳本:

use strict; 
use warnings; 

BEGIN {push(@INC, split(':', $ENV{PERL_TEST_LIBS}))}; 

use Program::Plist::Pl; 

my $obj = Program::Plist::Pl->new(); 

計劃:: ::的plist文件PL:

package Program::Plist::Pl; 

use Moose; 
use namespace::autoclean; 

use Program::Types qw(Pattern); # <-- Removing this fixes error 
use Program::Plist::Pl::Pattern; 

sub BUILD { 
    my $pattern_obj = Program::Plist::Pl::Pattern->new(); 
} 

__PACKAGE__->meta->make_immutable; 

1; 

計劃::類型file:

package Program::Types; 

use MooseX::Types -declare => [qw(Pattern)]; 

class_type Pattern, {class => 'Program::Plist::Pl::Pattern'}; 

1; 

而Program :: Plist :: Pl :: Patte RN文件:

package Program::Plist::Pl::Pattern; 

use Moose; 
use namespace::autoclean; 

__PACKAGE__->meta->make_immutable; 

1; 

注:雖然我不需要在上面的代碼從Program::TypesPattern型,我在被剝離其他代碼做。 PERL_TEST_LIBS env var我從中拉出INC路徑只包含到項目模塊的路徑。沒有其他模塊從這些路徑加載。

看起來MooseX::Types定義爲Pattern是造成問題,但我不知道爲什麼。文檔顯示了我正在使用的語法,但有可能我誤用了class_type,因爲沒有太多關於它的說法。意圖是能夠使用Pattern進行類型檢查,通過MooseX::Params::Validate驗證參數是否爲Program::Plist::Pl::Program對象。

我發現,通過直接調用從tmp18.pl包裝結果Pattern->new中沒有錯誤,即使Program::TypesPattern型進口從公式除去中間類Program::Plist::Pl

+0

似乎Program :: Plist :: Pl :: Pattern-> new被誤認爲Pattern-> new,其中Pattern是我的MooseX定義的類型。因此,不是創建一個Program :: Plist :: Pl :: Pattern實例,而是試圖創建一個Pattern類型對象的實例。 – 2011-01-11 00:18:43

回答

5

當你說

package Program::Plist::Pl; 
... 
use Program::Types qw(Pattern); 

要導入一個名爲Pattern成包Program::Plist::Pl子程序。其完全合格的名稱是Program::Plist::Pl::Pattern。因此,

Program::Plist::Pl::Pattern->new(); 

解析爲

Program::Plist::Pl::Pattern()->new(); 

,而不是

'Program::Plist::Pl::Pattern'->new(); 

這是你的意思。你可以用明確的引號將它寫出來(如果你願意的話),但這是一個惱人的特例。另一種解決方案是將類型重命名爲不會與包名衝突的內容(如PatternObj)。

namespace::autoclean對此沒有幫助。它可以防止人們調用導入的subs作爲方法。但是你直接調用Program::Plist::Pl::Pattern(),然後在其返回值上調用一個方法。

+0

順便說一句,這是遵循Perl的「社區標準」命名約定的一個很好的理由:TitleCase類名稱,lowercase_sub_names_with_underscores。如果您將TitleCase用於類名稱和子名稱,則由於在類名稱的最右側組件(例如,$ product-> Vendor()用於獲取的對象屬性的頻率/設置Product :: Vendor對象)。 – 2011-01-11 01:52:22