2011-01-10 3 views
3

恥ずかしいほどの時間をデバッグした後、私はついに、this issueを単純なテストケースに切り捨てました。私は、なぜそれが失敗しているのかを理解する助けを謙虚に要請するでしょう。 :)ここで私が得ているエラーメッセージです:MooseX :: Types宣言の問題、厳しいテストケース:)

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 :: P1のファイル:

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; 

プログラム::タイプファイル:

package Program::Types; 

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

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

1; 

さらに、プログラム:: Plist :: Pl :: Patte RNファイル:

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

use Moose; 
use namespace::autoclean; 

__PACKAGE__->meta->make_immutable; 

1; 

注:私は上記のコードでProgram::TypesからPatternタイプを必要としませんが、私は取り除かれ、他のコードで行います。私がINCパスを引っ張っているPERL_TEST_LIBSのenv varには、プロジェクトモジュールへのパスしか含まれていません。これらのパスからロードされる他のモジュールはありません。

PatternMooseX::Typesの定義は問題を引き起こしているようですが、その理由はわかりません。ドキュメントは私が使用している構文を示していますが、それについてはあまり言及されていないので、私はclass_typeを誤用している可能性があります。意図はMooseX::Params::ValidateによってPatternをタイプチェックに使用して、引数がProgram::Plist::Pl::Programオブジェクトであることを確認することです。

私はProgram::TypesPatternタイプがインポートされた場合でも、直接、エラーなしでtmp18.plラッパー結果からPattern->newを呼び出すことにより、式から介在クラスProgram::Plist::Plを削除することを発見しました。

+0

Program :: Plist :: Pl :: Pattern-> newはPattern-> newと誤解されているようですが、PatternはMy MoXX定義の型です。したがって、Program :: Plist :: Pl :: Patternのインスタンスを作成する代わりに、Pattern型オブジェクトのインスタンスを作成しようとしています。 –

答えて

5

あなたは

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

を言うとき、あなたがパッケージProgram::Plist::PlPatternという名前のサブルーチンをインポートしています。完全修飾名はProgram::Plist::Pl::Patternです。したがって、

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

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

の代わりに、あなたは何を意味するのかである

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

として解析します。あなたが望むならそれを明示的な引用符で書くことができます(そしてうまくいきます)が、それは厄介な特別なケースです。もう1つの解決策は、パッケージ名と矛盾しないように型の名前を変更することです(たとえばPatternObj)。

namespace::autocleanこれは役に立ちません。これは、人々がメソッドとしてインポートされたサブを呼び出すのを防ぎます。しかし、Program::Plist::Pl::Pattern()を直接呼び出してから、その戻り値でメソッドを呼び出しています。

+0

これは、偶然にも、Perlの "コミュニティ標準"命名規則、TitleCaseクラス名、lowercase_sub_names_with_underscoresに従う優れた理由です。 TitleCaseをクラス名とサブネームの両方に使用すると、クラス名の右端のコンポーネントの名前に基づいてオブジェクト属性の頻度が高いため、このような衝突が発生する可能性があります(例:$ product-> Vendor()/Set Product :: Vendorオブジェクト)。 –

+0

cjm - どうやら、私はバグが腹を立てていることが明らかになった:)私は最終的に何が起こっていたのか決定してうれしい。これは私に一日のナッツを送りました。しかし、私はその時間に多くのことを学んだので、私はかなりの時間をかけて学びました:) ジョン - あなたは命名基準に絶対に間違いありません。私はすべての私のコードに従います。しかし、以前はMooseを使用したことはありません。すべてのドキュメントでは、型定義にUpperCase型の命名規則を使用しています。そのため、明示的な命名プロトコルを使用しました。 –

関連する問題