MooseのTypeConstraintsのインターフェイスがよくない
Moose::Util::TypeConstraintsのSYNOPSISより:
use Moose::Util::TypeConstraints; type 'Num' => where { Scalar::Util::looks_like_number($_) }; subtype 'Natural' => as 'Int' => where { $_ > 0 }; subtype 'NaturalLessThanTen' => as 'Natural' => where { $_ < 10 } => message { "This number ($_) is not less than ten!" };
このasやらwhereやらは一見すると名前付き引数に見えるが,現状では実際には単なるシンタクスシュガーでしかない。定義は以下の通り。
sub as { @_ } sub from { @_ } sub where (&) { $_[0] } sub via (&) { $_[0] }
つまり,これらは実際には単なるコメント以上の意味はなく,各々の引数は順番どおりに渡さなければならない。これらを名前付き引数と考えるのは誤りである。
なぜ以下のような名前付き引数をもつインターフェイスにしなかったのかはよく分からない。
subtype 'Natural', as => 'Int', where => sub{ $_ > 0 };
更に悪いことに,optimized_asとmessageは実際に名前付き引数なので,この二つは,そしてこの二つだけは,交換可能である。定義は以下の通り。
sub message (&) { +{ message => $_[0] } } sub optimize_as (&) { +{ optimized => $_[0] } }
しかし,これはname => valueペアを渡すよりも効率は悪い。
これに対して,Mooseのhas()は名前付き引数を受け取る。つまり,Mooseシステムの一部でありながらMoose本体とは異なるインターフェイスである点もよくない。