読者です 読者をやめる 読者になる 読者になる

はちゅにっき

こっちのブログはまったり更新

Mouse::Getopt が分かってない

Mouse::Getopt を使ってみよぅ。
ということで挑戦。
が、失敗。たすけて!

引数として Locale *1 を与えると、それを単純に表示してくれる。
それだけ。

$ ./test.pl --locale ja_JP
ja_JP

こんな感じのを作りたい。

  • test.pl
    • new_with_options でMyApp::Test を呼ぶことで、Getopt のお力を借りる。
#!/usr/bin/env perl

use lib qw/ lib /;
use MyApp::Test;

MyApp::Test->new_with_options->run;
  • MyApp/Test.pm
    • Locale を表示する部分と、Locale のメソッド定義を与える
package MyApp::Test;

use MyApp::Types qw/ Locale /;

use Any::Moose;
with any_moose('X::Getopt');

has locale => (
    is       => 'ro',
    isa      => Locale,
    required => 1,
);

__PACKAGE__->meta->make_immutable;
no Any::Moose;

sub run
{
    my $self = shift;
    print $self->locale, "\n";
}

1;
  • MyApp/Types.pm
    • Locale 型を定義する
package MyApp::Types;

use Any::Moose;
use Any::Moose (
    'X::Types' => [ -declare => [qw/ Locale /] ],
    'X::Types::'.any_moose(), [qw/ Str /],
);

do {
    subtype Locale,
        as Str,
        where { /^[a-z]{2}_[A-Z]{2}$/ };
};

1;


実行してみる。

$ env ANY_MOOSE=Moose ./test.pl --locale ja_JP
ja_JP

やったね!

  • Mouse
$ env ANY_MOOSE=Mouse ./test.pl --locale ja_JP
Attribute (locale) does not pass the type constraint because: Validation failed for 'MyApp::Types::Locale' failed with value 1 at /home/my/local/lib/perl5/site_perl/5.10.0/Mouse/Meta/Attribute.pm line 240
        Mouse::Meta::Attribute::verify_type_constraint_error('Mouse::Meta::Attribute=HASH(0x8edce88)', 'locale', 1, 'Mouse::Meta::TypeConstraint=HASH(0x8ddcaa0)') called at (eval 16) line 30
        Mouse::Meta::Method::Constructor::__ANON__('MyApp::Test', 'ARGV', 'ARRAY(0x8da8710)', 'extra_argv', 'ARRAY(0x8da8980)', 'locale', 1) called at /home/my/local/lib/perl5/site_perl/5.10.0/MouseX/Getopt.pm line 43
        MouseX::Getopt::new_with_options('MyApp::Test') called at test.pl line 6

はい、泣きそう。
where の部分をコメントアウトして実行してみると

$ env ANY_MOOSE=Mouse ./test.pl --locale ja_JP
1


どうやら常に 1 が渡っているみたいなんだけど、なんでだろうなー。

追記

isa => Locale を isa => 'Str' にして Validation しなければうまく動くみたい。
つまり、Mouse::Getopt の動作というより、subtype のあたりを理解してないのかなー。

*1:ただしロケールには、条件を与える => /^[a-z]{2}_[A-Z]{2}$/