The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Validator::Custom::Guides::Ja - Validator::Customの日本語ガイド

ガイド

1. 基本的な使用方法

新しいValidator::Customオブジェクトの生成。

    use Validator::Custom;
    my $vc = Validator::Custom->new;

バリデーションにおけるデータはハッシュリファレンスである必要があります。

    my $data = { 
        age => 19, 
        name => 'Ken Suzuki'
    };

制約関数の登録。 制約は、値が正しいかどうかをチェックするためのもので、 サブルーチンのリファレンスでなければなりません。

    $vc->register_constraint(
        int => sub {
            my $value    = shift;
            my $is_valid = $value =~ /^\d+$/;
            return $is_valid;
        },
        not_blank => sub {
            my $value = shift;
            my $is_valid = $value ne '';
            return $is_valid;
        },
        length => sub {
            my ($value, $args) = @_;
            my ($min, $max) = @$args;
            my $length = length $value;
            my $is_valid = $length >= $min && $length <= $max;
            return $is_valid;
        },
    );

バリデーションのためのルールは、 パラメータ名と制約関数のペアによる特別なフォーマットを持ちます。 フォーマットの詳細については「3. ルールの文法」で解説しています。

    my $rule = [
        age => [
            'int'
        ],
        name => [
            ['not_blank',        "Name must be exists"],
            [{length => [1, 5]}, "Name length must be 1 to 5"]
        ],
        # PARAMETER_NAME => [
        #    CONSTRIANT_EXPRESSION1
        #    CONSTRAINT_EXPRESSION2
        # ]
    ];

データのバリデーション。validateメソッドはValidator::Custom::Result オブジェクトを返却します。

    my $result = $vc->validate($data, $rule);

2. バリデーションの結果

Validator::Custom::Resultオブジェクトはバリデーションの結果を 持ちます。詳細はValidator::Custom::Resultを見てください。

サンプル:

存在しないパラメータを持つかどうか、また不正なパラメータを持つかどうか をチェックします。

    if ($result->has_missing) {
        # ...
    }
    elsif ($result->has_invalid) {
        
        print $result->message('title')
          unless $result->is_valid('title');
        
        print $result->message('author')
          unless $result->is_valid('author');
    }

すべてのメッセージの取得

    if ($result->has_missing) {
        # ...
    }
    elsif ($result->has_invalid) {
        
        my $messages = $result->messages;
    }

HTML::FillInFormとの連携

    unless ($result->is_ok) {
        
        my $html = get_something_way();
        
        # Fill in form
        $html = HTML::FillInForm->fill(
            \$html, $result->raw_data,
            ignore_fields => $result->invalid_params
        );
        
        # Do something
    }

3. ルールの文法

基本的な文法

「ルール」は配列のリファレンスでなければなりません。 これは不正なパラメータ名の順序を維持するためです。

    my $rule = [
    
    ];

「ルール」は、「パラメータ名」と「制約表現」の複数の組を含みます。

    my $rule = [
        name => [
            'not_blank'
        ],
        age => [
            'not_blank',
            'int'
        ]
        price => {default => 1000, message => 'price must be integer'} => [
            'int'
        ]

        # パラメータ名 => (オプション) => [
        #    制約表現1
        #    制約表現
        # ]
    ];

制約表現

制約表現は次の四つのうちのひとつです。

  1. 制約関数名

        制約関数名
  2. 制約関数名とメッセージ

        [制約関数名, メッセージ]
  3. 制約関数名と引数

        {制約関数名 => 引数}
  4. 制約関数名と引数とメッセージ

        [{制約関数名 => 引数}, メッセージ]

サンプル:

    my $rule = [
        age => [
            # 1. 制約関数名
            'defined',
            
            # 2. 制約関数名とメッセージ
            ['not_blank', 'Must be not blank'],
            
            # 3. 制約関数名と引数
            {length => [1, 5]},
            
            # 4. 制約関数名と引数とメッセージ
            [{regex => qr/\d+/}, 'Invalid string']
        ]
    ];

ルールオプション

ルールにはオプションを設定することができます。

    my $rule = [
        price => {default => 1000, message => 'price must be integer'} => [
            'int'
        ]
    ];
1. message

結果が不正なパラメータを持つときのためのメッセージ。 個々にメッセージが設定されない場合は、このメッセージが利用されます。

     {message => "This key is invalid"}
2. default

デフォルト値。この値は、結果が存在しないパラメータを持つときか、 不正なパラメータを持つときに設定されます。

    {default => 5}
3. copy

結果のdataにパラメータをコピーするかどうかをしています。 デフォルトは1で、コピーを行います。

    {copy => 0}

マルチパラメータバリデーション

複数パラメータのバリデーションが利用できます。

    $data = {password1 => 'xxx', password2 => 'xxx'};

    $rule = [
        {password_check => [qw/password1 password2/]} => [
            ['duplication', 'Two password must be equal']
        ]
    ];

"password1"と"password2"はパラメータ名です。 "password_check"は結果のキーです。

マルチバリューバリデーション

パラメータの値がハッシュのリファレンスであった場合に、 マルチバリューバリデーションが利用できます。 「@」マークを制約関数名の前に追加してください。

    $data = {
        nums => [1, 2, 3]
    };
    
    $rule = [
        'nums' => [
            '@int'
        ]
    ];

OR条件によるバリデーション

OR条件によるバリデーションが利用できます。 パラメータ名を繰り返し書いてください。

    $rule = [
        email => [
            'blank'
        ],
        email => [
            'not_blank',
            'emai_address'
        ]
    ];

否定のバリデーション

制約名の前に「!」を付けることによって、 制約関数の否定を行うことができます。

    $rule = [
        age => [
            '!int';
        ],
    ];

この意味は「age」は「int」ではないという意味です。 これはマルチバリューバリデーションと組み合わせることができます。

    $rule = [
        ages => [
            '@!int';
        ]
    ];

ルールの共有

すべてのパラメータでルールを共有することができます。 共有ルールは制約表現のそれぞれのリストの先頭に 追加されます。

    $vc->shared_rule([
        ['defined',   'Must be defined'],
        ['trim'],
        ['not_blank', 'Must be not blank']
    ]);

4. 制約関数の仕様

制約関数の仕様を解説します。

    # Register constraint
    $vc->register_constraint(
        consrtaint_name => sub {
            my ($value, $args, $vc) = @_;
            
            # Do something
            
            return $is_valid;
        }
    )

引数と戻り値

制約関数は3つの引数を受け取ります。

  1. (ルールの)引数

  2. Validator::Customオブジェクト

1. 値

これはデータの値です。

    my $data = {name => 'Ken Suzuki'};

この例では、値は「Ken Suzuki」です。

2. ルールの引数

ルールの中で制約関数に引数を渡すことができます。

    my $rule = [
        name => [
            {length => [1, 5]}
        ]
    ];

この例では、引数は「[1, 5]」になります。

また制約関数は値が正しいかどうかを チェックするための値を返却する必要があります。

マルチパラメータバリデーションにおいては、 値は配列のリファレンスにパックされます。 値は「['xxx', 'xxx']」のようになります。

    $data = {password1 => 'xxx', password2 => 'xxx'};

    $rule = [
        {password_check => [qw/password1 password2/]} => [
            ['duplication', 'Two password must be equal']
        ]
    ];

フィルタ関数

制約関数は、変換した値を返却することもできます。 もし変換された値を返却したい場合は、 配列のリファレンスを返す必要があります。 一番目の要素は「値が正しいかどうかを確認するための値」、 二番目の引数は、「変換された値」です。

    $vc->register_constraint(
        trim => sub {
            my $value = shift;
            
            $value =~ s/^\s+//;
            $value =~ s/\s+$//;
            
            return [1, $value];
        }
    );

5. 拡張

Validator::Customを拡張するのは簡単です。 制約関数を登録するには、継承したクラスの コンストラクタの中でregister_constraintメソッドを 使用します。

    package YourValidator;
    use base 'Validator::Custom';
    
    sub new {
        my $self = shift->SUPER::new(@_);
        $self->register_constraint(
            defined  => sub { defined $_[0] }
        );
        return $self;
    }
    
    1;
    

Validator::Custom::HTMLFormはよいサンプルです。

6. 応用的な機能

データフィルタリング

データがハッシュリファレンスでない場合は、 data_filterメソッドを使ってデータをハッシュリファレンス に変換することができます。

    $vc->data_filter(
        sub { 
            my $data = shift;
            
            # Convert data to hash reference
            
            return $data;
        }
    );

メッセージの蓄積

デフォルトでは、すべてのパラメータがvalidateメソッドによって チェックされます。もしデータが正しいかどうかのみを確かめたい 場合は、不正な値が見つかったときにバリデーションを終えたほう がよいです。error_stockを0に設定すれば、 バリデーションは不正な値が見つかるとすぐに終了します。

    $vc->error_stock(0);