JUST FOR FUN

Twitter:@okwra Facebook:ayato.ookawara GitHub:@tearon4 other:@taiga006

サブルーチンの引数をバリデートするData::Validatorの拡張を理解したい

プライベートでもお仕事でもお世話になっています。

github.com

基本的にはHASH or HASH_REF の形での値の引き渡しができることは知ってるのだが、withを使った拡張によっていくつか応用が効くみたいであり、それをイマイチ把握してなかったので今回は適当なスクリプトを書いてそれらを確認してみた。

package Foo;
use strict;
use warnings;
use feature 'state';
use Data::Validator;

sub HeronsFormula {
    state $rule = Data::Validator->new(
        a => { isa => 'Int' },
        b => { isa => 'Int' },
        c => { isa => 'Int', default => 5 },
    )->with("Method","Sequenced","NoThrow","AllowExtra"); # 同時に複数の拡張を適用できる

    my ($self, $args) = $rule->validate(@_); #"Method"でメソッドとして利用可

    if($rule->has_errors) {
        my $errors = $rule->clear_errors;
        for my $e (@{$errors}) {
            print $e->{message},"\n";
        }
        return;
    }else {
        my $a = $args->{a};
        my $b = $args->{b};
        my $c = $args->{c};
        my $s = ($a + $b + $c)/2;
        return sqrt($s * ($s - $a) * ($s - $b) * ($s - $c));
    }
}

print Foo->HeronsFormula(3, 4, 5),"\n";            # "Sequenced"で引数をリストにできる
print Foo->HeronsFormula(3, 4, 5, 'hoge'),"\n";    # "AllowExtra"で余分な引数を受けられる
print Foo->HeronsFormula(3, 4),"\n";               # (defaultでc = 5となっている)

print Foo->HeronsFormula("dokodoko","zukazuka", "queque");
# "NoThrow"で例外ではなくエラー属性を返す
# Invalid value for 'a': Validation failed for 'Int' with value dokodoko
# Invalid value for 'b': Validation failed for 'Int' with value zukazuka
# Invalid value for 'c': Validation failed for 'Int' with value queque

他にも

SmartSequenced ...順序付きスタイルと名前付きスタイルを混合させることが出来る(ハイブリットっぽくて便利だけどこんがらがりそう)
    # mixed style(recommend)
    smart_seq( 'foo', { val => 'bar' }, { o1 => 'yes' } );
    smart_seq( 'foo', { val => 'bar' } );

StrictSequenced ...名前付きスタイルは使えない(より厳密)
    seq( 'bar' );          # seq() will get { foo => 'bar' }
    seq({ foo => 'bar' }); # named style are NOT available!

などある様子。

今回の参考ページ

d.hatena.ne.jp

hirobanex.net

blue1st-tech.hateblo.jp