2017-07-11 14 views
1

私はPerlを少し新しくしました。 、クラスを宣言するときに、Mooseでエイリアスを使用しても動作しないようです。

Attribute (attribute) does not pass the type constraint because: Validation failed for 'ArrayRef[D]' with value ARRAY(0x7f2b658b51c0) 

をしかし:オブジェクトを作成するとき

package A::B::C; 
use strict; 
use warnings; 
use Moose; 
use aliased 'A::B::D'; 
has 'attribute' => (isa => 'ArrayRef[D]', is => 'ro', required => 1); 

:ムースは文句を言いしかしこれが失敗

use aliased 'A::B::C'; 
use aliased 'A::B::D'; 
my $aref = [D->new()]; 
C->new($aref); 

私は次のようにクラスを使用/定義しようとしていますエイリアスを使用しないように切り替えると、もちろん動作します(もちろんそうです):

package A::B::C; 
use strict; 
use warnings; 
use Moose; 
use A::B::D; 
has 'attribute' => (isa => 'ArrayRef[A::B::D]', is => 'ro', required => 1); 

私の質問はなぜエイリアス使用ビットがムースで動作しないのですか?

おかげ

答えて

1

ムースを約use aliasedを知りません。プラグマuse aliasedはPerlの上のハックです。クラス名を返す短い名前のサブルーチンを作成するだけです。だから、

use aliased 'A::B::D'; 

use A::B::D; 

sub D() { 'A::B::D' } 

と等価であるあなたがD->new()のようなものを言うとき、PerlはDという名前のサブルーチン(定数)があることに気づくとDを解釈し、その後

aliased.pm#L45を参照してください)サブルーチンコールとして、結果に対してメソッド呼び出しを行います。 (普通のようにDを文字列定数として解釈するのではなく)。 Perlにさえ、Dは実際にパッケージ名ではありません。パッケージ名のように機能するもの!

さらに、Mooseには、型宣言の構文解析のための独自のシステムがあります。そのうちのどれもaliasedを知らないので、Mooseは認識されない型を(グローバル)パッケージ名として扱うというデフォルト動作を使用しています。

あなたはどのようにaliased作品を理解している場合、あなたは

has 'attribute' => (isa => 'ArrayRef['.D.']', is => 'ro', required => 1); 

を行うことによって、それを活用することができますが、それは

Type names are global throughout the current Perl interpreter

と、完全に使用していることを覚えておくことはおそらく良いでしょう-qualifiedパッケージ名をどこでも型として使用するか、Type::Tinyを使用して

package A::B::C; 

use Moose; 

use aliased 'A::B::D'; 

use Types::Standard qw/ ArrayRef /; 
use Type::Utils qw(class_type); 

has 'attribute' => (isa => ArrayRef[class_type D], is => 'ro', required => 1); 

(だけのためuse aliasedの可能性、Dの前後に引用符がないことに注意してください!)。

Type::Tinyはおそらくムーゼ型よりも速いので、とにかくそれを考慮する必要があります)。

+0

は、インポートに短い名前を使用するための標準的な/推奨の方法ですか?私が確かめたいのは、私が使っているアプローチには、それに関連する問題がなく、パス全体を指定する代わりに使われるときだけであるということです。 – user2103008

関連する問題