Data::Validatorの凝った使い方

https://github.com/gfx/p5-Data-Validatorが大体できたのでリリースしました。
基本的には名前で引数を指定する関数向けですが、メソッド用に対応したりリストスタイルで引数を指定したりする拡張機能もあります。
まず、$validator->with('Method') でメソッド用になります。ただし、第一引数の型はいまのところ指定できません:

use feature 'state';
use Data::Validator;
sub Foo::add {
    state $rule = Data::Validator->new(
        a => 'Int',
        b => 'Int',
    )->with('Method');
    my($self, $args) = $rule->validate(@_);
    return $args->{a} + $args->{b};
}
print Foo->add(a => 10, b => 20); # => 30

$validator->with('Sequenced') で名前ベースでなくすることもできます。このとき、関数の最後の引数がハッシュリファレンスだと、その部分のみ名前による引数渡しとみなします。またいずれにせよ、参照は名前で行います。

use feature 'state';
use Data::Validator;
sub add {
    state $rule = Data::Validator->new(
        a => 'Int',
        b => 'Int',
    )->with('Sequenced');
    my $args = $rule->validate(@_);
    return $args->{a} + $args->{b};
}
print add(10, 20);              # sequenced style
print add({ a => 10, b => 20}); # named style
print add(10, { b => 20 });     # mixed style

またデフォルトのvalidate()は未知の引数名に対して例外を発生させますが、$validator->with('AllowExtra')は例外を発生させる代わりにそのような余分な引数をリストで返すようにします。

use feature 'state';
use Data::Validator;
sub foo {
    state $rule = Data::Validator->new(
        a => 'Int',
        b => 'Int',
    )->with('AllowExtra');
    my($args, %extra) = $rule->validate(@_);
    # ...
}
foo(a => 10, b => 20, c => 30); # %extra = (c => 30) になる

なお、$validator->with('Method', 'Sequenced')のように同時に複数の拡張を適用することもできます。