ブログトップ 記事一覧 ログイン 無料ブログ開設

サンプルコードによるPerl入門 produced by 木本裕紀

3000-01-01

サンプルコードによるPerl入門 - 目次

 サンプルコードによるPerl入門は、サンプルコードを中心としたPerlの入門サイトです。またPerl中級者、上級者向けの内容も豊富に扱っていますので、順番に学習していくと、実際の仕事に必要な知識も身につくようになっています。

続きを読む

2015-12-12

Validator::Custom日本語訳 - HTMLフォームのバリデーション、簡潔でよい柔軟性を持つ

名前

Validator::Custom - HTMLフォームのバリデーション、簡潔でよい柔軟性を持つ

使い方

  use Validator::Custom;
  my $vc = Validator::Custom->new;
  
  # 入力データ
  my $id = 1;
  my $name = 'Ken Suzuki';
  my $price = ' 19.23 ';
  my $favorite = ['001', '002'];
  
  # バリデーションオブジェクトの作成
  my $validation = $vc->validation;
  
  # 「ID」が整数であることをチェック
  if (!$vc->check($id, 'int')) {
    # 失敗時のメッセージを追加
    $validation->add_failed(id => 'id must be integer');
  }
  
  # 「名前」に長さがあることをのチェック
  if (!(length $name)) {
    $validation->add_failed(name => 'name must have length');
  }
  # 「名前」の長さが30より小さいことをチェック
  elsif (!(length $name < 30)) {
    $validation->add_failed(name => 'name is too long');
  }
  
  # 左右の空白を取り除くために「価格」をフィルタリング
  $price = $vc->filter($price, 'trim');

  # 「価格」が、小数部が2桁以内の数値であることをチェック
  if (!$vc->check($price, , 'number', {decimal_part_max => 2})) {
    # Set default value if validation fail
    $price = 20.25;
  }
  
  # 「お気に入り」のそれぞれの値を、「trim」フィルター関数を使ってフィルタリング
  $favorite = $vc->filter_each($favorite, 'trim');
  
  # 「お気に入り」が少なくともひとつの値を持つことをチェック
  if (@$favorite == 0) {
    $validation->add_failed(favorite => 'favorite must be selected more than one');
  }
  # 「お気に入り」が「001」「002」「003」のうちのどれかひとつであることをチェック
  elsif (!($vc->check_each($favorite, 'in',  ['001', '002', '003']))) {
    $validation->add_failed(favorite => 'favorite is invalid');
  }
  
  # バリデーションの結果が正しいかをチェック
  if ($validation->is_valid) {
    # ...
  }
  else {
    
    # どのパラメーターが失敗したのかをチェック
    unless ($validation->is_valid('name')) {
      # ...
    }
    
    # 失敗したすべてのパラメーターの名前を取得
    my $failed = $validation->failed;

    # 失敗したひとつのパラメーターのメッセージを取得
    my $name_message = $validation->message('name');
    
    # 失敗したすべてのパラメーターのメッセージを取得
    my $messages = $validation->messages;
    
    # 失敗したすべてのパラメーターの名前とメッセージをハッシュのリファレンスとして取得
    my $messages_h = $validation->messages_to_hash;
  }

解説

Validator::CustomはHTMLフォームのバリデータで、簡潔さとよい柔軟性を備えています。

特徴は以下のようになっています。

  • いくつかのチェック関数がデフォルトで利用できます。ascii_graphic,int, number, inなど。
  • いくつかのフィルター関数がデフォルトで利用できます。trim, remove_blankなど。
  • あなた自身のチェック関数とフィルター関数を追加することができます。
  • 簡潔なバリデーションオブジェクト利用できます。失敗したパラメーターの名前とメッセージを順序を保って保存できます。

ガイド

1. 基礎

1. 新しいValidator::Customオブジェクトを作成

まず最初にnewメソッドを使って、Validator::Customオブジェクトを作成します。

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

2.バリデーションのための入力データの準備

次に、入力データを準備します。

  my $id = 1;
  my $name = 'Ken Suzuki';
  my $price = ' 19.23 ';
  my $favorite = ['001', '002'];

3. バリデーションオブジェクトの作成

次に、validationメソッドを使って、新しいバリデーションオブジェクトを作成します。

  my $validation = $vc->validation;

これは、

失敗したパラメーター名とメッセージを保存するための、Validator::Custom::Validationオブジェクトです。

4. 入力データの検証

  # 「ID」が整数であることをチェック
  if (!$vc->check($id, 'int')) {
    # 失敗時のメッセージを追加
    $validation->add_failed(id => 'id must be integer');
  }

値が、整数であることをチェックするためにintチェック関数を使用することができます。intチェック関数はデフォルトのチェック関数です。チェック関数はcheckメソッドを通して、利用することができます。

チェックが成功しなかった場合は、失敗したパラメーターの名前とメッセージを、Validator::Custom::Validationクラスのadd_failedメソッドを使って追加することができます。

  # 左右の空白を取り除くために「価格」をフィルタリング
  $price = $vc->filter($price, 'trim');

左右のスペースを削除するために、trimフィルター関数を使うことができます。

  # 「お気に入り」のそれぞれの値を、「trim」フィルター関数を使ってフィルタリング
  $favorite = $vc->filter_each($favorite, 'trim');

「お気に入り」のそれぞれの値をフィルターするために、filter_eachメソッドを使うことができます。

  # 「お気に入り」が少なくともひとつの値を持つことをチェック
  if (@$favorite == 0) {
    $validation->add_failed(favorite => 'favorite must be selected more than one');
  }
  # 「お気に入り」が「001」「002」「003」のうちのどれかひとつであることをチェック
  elsif (!($vc->check_each($favorite, 'in',  ['001', '002', '003']))) {
    $validation->add_failed(favorite => 'favorite is invalid');
  }

「お気に入り」のそれぞれの値をチェックするために、check_eachメソッドを使うことができます。

デフォルトのチェック関数とフィルター関数を知りたい場合は、「チェック関数」と「フィルター関数」の項目を見て下さい。

2 バリデーションオブジェクトの扱い

すべての入力データが正しいことをチェックするにはis_validメソッドを使用します。

  # バリデーションの結果が正しいことを確認する
  if ($validation->is_valid) {
    # 成功
  }
  else {
    # 失敗
  }

もし、ひとつの入力データが正しいかどうかをチェックしたい場合は、is_validメソッドをパラメーターつきで使ってください。

  # どのパラメーターが失敗したかを確認
  unless ($validation->is_valid('name')) {
    # ...
  }

failedメソッドを使って、バリデーションに失敗したすべてのパラメーターの名前を取得できます。

  # バリデーションに失敗したすべてのパラメーターの名前を取得
  my $failed = $validation->failed;

messageメソッドを使って、バリデーションに失敗したパラメーターのメッセージを取得できます。

  # バリデーションに失敗したパラメーターのメッセージを取得
  my $name_message = $validation->message('name');

messagesメソッドを使って、バリデーションに失敗したすべてのパラメーターのメッセージを取得できます。

  # バリデーションに失敗したすべてのパラメーターのメッセージを取得
  my $messages = $validation->messages;

messages_to_hashメソッドを使って、バリデーションに失敗したすべてのパラメーターの名前とメッセージを、ハッシュリファレンス形式で取得できます。

  # 失敗したすべてのパラメーターの名前とメッセージをハッシュのリファレンスとして取得
  my $messages_h = $validation->messages_to_hash;

Validator::Custom::Validationも参考にしてください。

3 発展的な技術

1. チェック関数の追加

必要であれば、add_checkメソッドを使って、自分自身でチェック関数を追加できます。

  $vc->add_check(
    telephone => sub {
      my ($vc, $value, $arg) = @_;
      
      my $is_valid;
      if ($value =~ /^[\d-]+$/) {
        $is_valid = 1;
      }
      return $is_valid;
    }
  );

チェック関数は、みっつの引数をとります。最初の引数は、Validator::Customオブジェクト、二つ目の引数は、チェックするための値、三つ目の引数は、チェック関数への引数。

チェック関数は、戻り値として真か偽の値を返す必要があります。

2. フィルター関数の追加

必要であれば、add_filterメソッドを使って、自分自身でフィルター関数を追加できます。

  $vc->add_filter(
    to_upper_case => sub {
      my ($vc, $value, $arg) = @_;
      
      my $new_$value = uc $value;
                  
      return $new_value;
    }
  );

フィルター関数は、みっつの引数をとります。最初の引数は、Validator::Customオブジェクト、二つ目の引数は、フィルタリングするための値、三つ目の引数は、フィルター関数への引数。

フィルター関数は、フィルタリングの結果を返却する必要があります。

チェック関数

Validator::Customは、次のデフォルトのチェック関数を持ちます。すべてのチェック関数はcheckメソッドを使って呼び出すことができます。

int
  my $value = 19;
  my $is_valid = $vc->check($value, 'int');

整数値かどうかをチェックする。

正しい値の例

  "-10"
  "234"

不正な値の例

  "10.11"
  "abc"

もし値の範囲のチェックも行いたいのであれば、次のように書くことができます。

  my $is_valid =  $vc->check($value, 'int') && $value > 0;
number
  my $is_valid = $vc->check($value, 'number');

値が数値であるかどうかをチェックします。数値というのは、整数と小数を意味します。

正しい値の例:

  '1'
  '123'
  '123.456'
  '-1'
  '-100'
  '-100.789'

不正な値の例:

  'a';
  '1.a';
  'a.1';

decimal_part_maxオプションを使って、小数部の最大桁数を指定することもできます。

  my $is_valid = $vc->check($value, 'number', {decimal_part_max => 3});

正しい値の例:

  '123'
  '123.456'
  '-100.789'

不正な値の例:

  '123.4567'
  '-100.7891'
ascii_graphic
  my $is_valid = $vc->check($value, 'ascii');

値がAsciiのグラフィック文字(16進の「21-7e」)であるかをチェックします。一般的には、パスワードの文字をチェックするために利用します。

正しい値の例:

  "Ken!@-"

不正な値の例:

  "aa aa"
  "\taaa"
in
  my $value = '001';
  my $is_valid = $vc->check($value, 'in', ['001', '002', '003']);

値が、与えられた複数の値のうちのひとつであるかどうかをチェックします。

正しい値の例:

  '001'
  '002'
  '003'

不正な値の例:

  '004'
  '005'

フィルター関数

Validator::Customは次のデフォルトのフィルター関数を持っています。すべてのフィルター関数はy C<filter> method.

trim
  my $new_value = $vc->filter($value, 'trim');

前後の空白を取り除きます。[ \t\n\r\f]というASCIIの空白文字だけではなく、ユニコードの空白文字も取り除くことに注意してください。

フィルタリングの例:

  入力: '   Ken  '
  出力: 'Ken'
remove_blank
  my $new_values = $vc->filter($values, 'remove_blank');

空文字と未定義の文字を配列のリファレンスから取り除きます。

フィルタリングの例:

  入力: [1, 2, '', undef, 4]
  出力: [1, 2, 4]

メソッド

Validator::CustomはObject::Simpleのすべてのメソッドを継承しており、次の新しいメソッドを実装しています。

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

新しいValidator::Customオブジェクトを生成します。

add_check
  $vc->add_check(int => sub { ... });

チェック関数を追加します。

サンプル:

  $vc->add_check(
    int => sub {
      my ($vc, $value, $arg) = @_;
      
      my $is_valid = $value =~ /^\-?[\d]+$/;
      
      return $is_valid;
    }
  );

チェック関数は、みっつの引数をとります。最初の引数は、Validator::Customオブジェクト、二つ目の引数は、チェックするための値、三つ目の引数は、チェック関数への引数。チェック関数は、戻り値として真か偽の値を返す必要があります。

add_filter
  $vc->add_filter(trim => sub { ... });

フィルター関数を追加します。

サンプル:

  $vc->add_filter(
    trim => sub {
      my ($vc, $value, $arg) = @_;
      
      $value =~ s/^\s+//;
      $value =~ s/\s+$//;
      
      return $value;
    }
  );

フィルター関数は、みっつの引数をとります。最初の引数は、Validator::Customオブジェクト、二つ目の引数は、フィルタリングするための値、三つ目の引数は、フィルター関数への引数。

フィルター関数は、フィルタリングの結果を返却する必要があります。

check
  my $is_valid = $vc->check($value, 'int');
  my $is_valid = $vc->check($value, 'int', $arg);

チェック関数を実行します。

第一引数は、チェックをする値です。第二引数は、チェック関数の名前です。第三引数は、チェック関数の引数です。

check_each
  my $is_valid = $vc->check_each($values, 'int');
  my $is_valid = $vc->check_each($values, 'int', $arg);

チェック関数を配列のリファレンスのすべての要素に対して実行します。ひとつ以上の値が不正であれば、check_eachメソッドは偽の値を返却します。

第一引数は、チェックをする値です。これは、配列のリファレンスである必要があります。第二引数は、チェック関数の名前です。第三引数は、チェック関数の引数です。

filter
  my $new_value = $vc->filter($value, 'trim');
  my $new_value = $vc->filter($value, 'trim', $arg);

フィルター関数を実行します。

第一引数は、フィルタリングを行う値です。第二引数は、フィルター関数の名前です。第三引数は、フィルター関数の引数です。

filter_each
  my $new_values = $vc->filter_each($values, 'trim');
  my $new_values = $vc->filter_each($values, 'trim', $arg);

フィルター関数を配列のリファレンスのすべての要素に対して実行します。

第一引数は、フィルタリングを行う値です。これは、配列のリファレンスである必要があります。第二引数は、フィルター関数の名前です。第三引数は、フィルター関数の引数です。

サンプル

バリデーションを行ういくつかのサンプルを紹介します。

パスワードのチェック:

  my $password = 'abc';
  my $password2 = 'abc';
  
  my $validation = $vc->validation;
  
  if (!length $password) {
    $validation->add_failed(password => 'password must have length');
  }
  elsif (!$vc->check($password, 'ascii')) {
    $validation->add_failed(password => 'password contains invalid characters');
  }
  elsif ($password ne $password2) {
    $validation->add_failed(password => "two passwords don't match");
  }
  
  if ($validation->is_valid) {
    # ...
  }
  else {
    # ...
  }

チェックボックス、少なくとも一つが選択されている。特定の値。

  my $favorite = ['001', '002'];

  my $validation = $vc->validation;
  
  if (@$favorite == 0) {

    $validation->add_failed(favorite => 'favorite must be selected at least 1');
  }
  elsif (!$vc->check($favorite, 'in', ['001', '002', '003'])) {
    $validation->add_failed(favorite => 'favorite have invalid value');
  }
  
  if ($validtion->is_valid) {
    # ...
  }
  else {
    # ...
  }

日付の文字列をTime::Pieceオブジェクトに変換:

  my $date = '2014/05/16';
  
  my $validation = $vc->validation;
  
  my $date_tp;
  if (!length $datetime) {
    $validation->add_failed(date => 'date must have length');
  }
  else {
    eval { $date_tp = Time::Piece->strptime($date, '%Y/%m/%d') };
    if (!$date_tp) {
      $validation->add_failed(date => 'date value is invalid');
    }
  }

日付時刻の文字列をTime::Pieceオブジェクトに変換:

  my $datetime = '2014/05/16 12:30:40';
  
  my $validation = $vc->validation;
  
  my $datetime_tp;
  if (!length $datetime) {
    $validation->add_failed(datetime => 'datetime must have length');
  }
  else {
    eval { $datetime_tp = Time::Piece->strptime($datetime, '%Y/%m/%d %H:%M:%S') };
    if (!$datetime_tp) {
      $validation->add_failed(datetime => 'datetime value is invalid');
    }
  }

FAQ

まだValidator::Customの0.xxのバージョンを使用しています。ドキュメントを見たいのですが。

Validator::Custom::Document::Version0を見てください。これは「Validator::Custom 0.xx」の完全なドキュメントです。

バージョン1.xxで気をつけなければならない点は何ですか。
  • in_array制約関数はinチェック関数にリネームされています。
  • trimフィルター関数は、[ \t\n\r\f]だけでなく、ユニコード文字列も削除するようになりました。
  • decimal制約関数はnumberチェック関数にリネームされ、簡易化されています。
  • date_to_timepiece制約関数はもう存在しません。代替の方法については、「サンプル」の「日付の文字列をTime::Pieceオブジェクトに変換」を参照してください。
  • datetime_to_timepiece制約関数はもう存在しません。代替の方法については、「サンプル」の「日付時刻の文字列をTime::Pieceオブジェクトに変換」を参照してください。
バージョン0.xxの制約関数に対応するチェック関数をどのように作成すればよいですか

いくつかのサンプルを見せます。

space

  $vc->add_check(space => sub {
    my ($vc, $value, $arg) = @_;
    return defined $value && $value =~ '^[ \t\n\r\f]*$' ? 1 : 0;
  });

http_url

  $vc->add_check(http_url => sub {
    my ($vc, $value, $arg) = @_;
    return defined $value && $value =~ /^s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+$/ ? 1 : 0;
  });

decimal

  $vc->add_check(decimal => sub {
    my ($vc, $value, $arg) = @_;

    return undef unless defined $value;
    
    my $digits_tmp = $arg;
    
    # Digit
    my $digits;
    if (defined $digits_tmp) {
      if (ref $digits_tmp eq 'ARRAY') {
        $digits = $digits_tmp;
      }
      else {
        $digits = [$digits_tmp, undef];
      }
    }
    else {
      $digits = [undef, undef];
    }
    
    # Regex
    my $re;
    if (defined $digits->[0] && defined $digits->[1]) {
      $re = qr/^[0-9]{1,$digits->[0]}(\.[0-9]{0,$digits->[1]})?$/;
    }
    elsif (defined $digits->[0]) {
      $re = qr/^[0-9]{1,$digits->[0]}(\.[0-9]*)?$/;
    }
    elsif (defined $digits->[1]) {
      $re = qr/^[0-9]+(\.[0-9]{0,$digits->[1]})?$/;
    }
    else {
      $re = qr/^[0-9]+(\.[0-9]*)?$/;
    }
    
    # Check value
    if ($value =~ /$re/) {
      return 1;
    }
    else {
      return 0;
    }
  }
バージョン0.xxの制約関数に対応するフィルター関数をどのように作成すればよいですか

いくつかのサンプルを見せます。

trim_collapse

  $vc->add_filter(trim_collapse => sub {
    my ($vc, $value, $arg) = @_;
    
    return undef unless defined $value;
    
    $value =~ s/[ \t\n\r\f]+/ /g;
    $value =~ s/^[ \t\n\r\f]*(.*?)[ \t\n\r\f]*$/$1/ms;

    return $value;
  });

trim_lead

  $vc->add_filter(trim_lead => sub {
    my ($vc, $value, $arg) = @_;
    
    return undef unless defined $value;

    $value =~ s/^[ \t\n\r\f]+(.*)$/$1/ms;

    return $value;
  });

trim_trail

  $vc->add_filter(trim_trail => sub {
    my ($vc, $value, $arg) = @_;
    
    return undef unless defined $value;

    $value =~ s/^(.*?)[ \t\n\r\f]+$/$1/ms;

    return $value;
  });

trim_uni

  $vc->add_filter(trim_uni => sub {
    my ($vc, $value, $arg) = @_;
    
    return undef unless defined $value;

    $value =~ s/^\s*(.*?)\s*$/$1/ms;

    return $value;
  });

trim_uni_collapse

  $vc->add_filter(trim_uni_collapse => sub {
    my ($vc, $value, $arg) = @_;

    return undef unless defined $value;
    
    $value =~ s/\s+/ /g;
    $value =~ s/^\s*(.*?)\s*$/$1/ms;

    return $value;
  });

trim_uni_lead

  $vc->add_filter(trim_uni_lead => sub {
    my ($vc, $value, $arg) = @_;
    
    return undef unless defined $value;
    
    $value =~ s/^\s+(.*)$/$1/ms;
    
    return $value;
  });

trim_uni_trail

  $vc->add_filter(trim_uni_trail => sub {
    my ($vc, $value, $arg) = @_;
    
    return undef unless defined $value;

    $value =~ s/^(.*?)\s+$/$1/ms;

    return $value;
  });

著者

木本裕紀(kimoto.yuki@gmail.com)

http://github.com/yuki-kimoto/Validator-Custom

2015-12-11

Validator::Custom 1.01をリリースしました。より簡潔で、柔軟なインターフェースの追加。

 Validator::Custom 1.01をリリースしました。より簡潔で、柔軟なインターフェースを追加して、ドキュメントを完全に書き換えました。互換性は完全に保たれています。

Validator::Custom

  • チェック関数とフィルタ関数を追加して、それぞれを、自由に利用できるように
  • バリデーションの結果を保存するオブジェクトを追加

使用方法

 チェック関数とフィルタ関数を自由に使えるようになっています。、結果をバリデーションオブジェクトに保存するように、記述します。さまざまな複雑なことを覚える必要はもうありません。

  use Validator::Custom;
  my $vc = Validator::Custom->new;
  
  # 入力データ
  my $id = 1;
  my $name = 'Ken Suzuki';
  my $price = ' 19.23 ';
  my $favorite = ['001', '002'];
  
  # バリデーションオブジェクトの作成
  my $validation = $vc->validation;
  
  # 「ID」が整数であることをチェック
  if (!$vc->check($id, 'int')) {
    # 失敗時のメッセージを追加
    $validation->add_failed(id => 'id must be integer');
  }
  
  # 「名前」に長さがあることをのチェック
  if (!(length $name)) {
    $validation->add_failed(name => 'name must have length');
  }
  # 「名前」の長さが30より小さいことをチェック
  elsif (!(length $name < 30)) {
    $validation->add_failed(name => 'name is too long');
  }
  
  # 左右の空白を取り除くために「価格」をフィルタリング
  $price = $vc->filter($price, 'trim');

  # 「価格」が、小数部が2桁以内の数値であることをチェック
  if (!$vc->check($price, , 'number', {decimal_part_max => 2})) {
    # Set default value if validation fail
    $price = 20.25;
  }
  
  # 「お気に入り」のそれぞれの値を、「trim」フィルター関数を使ってフィルタリング
  $favorite = $vc->filter_each($favorite, 'trim');
  
  # 「お気に入り」が少なくともひとつの値を持つことをチェック
  if (@$favorite == 0) {
    $validation->add_failed(favorite => 'favorite must be selected more than one');
  }
  # 「お気に入り」が「001」「002」「003」のうちのどれかひとつであることをチェック
  elsif (!($vc->check_each($favorite, 'in',  ['001', '002', '003']))) {
    $validation->add_failed(favorite => 'favorite is invalid');
  }
  
  # バリデーションの結果が正しいかをチェック
  if ($validation->is_valid) {
    # ...
  }
  else {
    
    # どのパラメーターが失敗したのかをチェック
    unless ($validation->is_valid('name')) {
      # ...
    }
    
    # 失敗したすべてのパラメーターの名前を取得
    my $failed = $validation->failed;

    # 失敗したひとつのパラメーターのメッセージを取得
    my $name_message = $validation->message('name');
    
    # 失敗したすべてのパラメーターのメッセージを取得
    my $messages = $validation->messages;
    
    # 失敗したすべてのパラメーターの名前とメッセージをハッシュのリファレンスとして取得
    my $messages_h = $validation->messages_to_hash;
  }

 ドキュメントの日本語訳は、近日中に公開予定です。

2015-12-10

Validator::Custom::Validation - バリデーションの結果

名前

Validator::Custom::Validation - バリデーションの結果

使い方

  my $validation = $vc->validation;
  
  $validation->add_failed(title => 'title is invalid');
  $validation->add_failed(name => 'name is invalid');
  
  # 正しいか
  my $is_valid = $validation->is_valid;
  my $title_is_valid = $validation->is_valid('title');
  
  # 失敗したパラメーターの名前
  my $failed = $validation->failed;
  
  # メッセージ
  my $messages = $validation->messages;
  my $title_message = $validation->message('title');
  my $messages_h = $validation->messages_to_hash;

メソッド

Validator::Custom::ValidationはObject::Simpleからすべてのメソッドを継承しており、次の新しいメソッドを実装しています。

new
  my $validation = Validator::Custom::Validation->new;

新しいValidator::Custom::Validationオブジェクトを生成します。

一般的にはこのメソッドは利用されません。Validator::Customvalidationメソッドを使うのがよいでしょう。

  my $validation = $vc->validation;
is_valid
  my $is_valid = $validation->is_valid;
  my $is_valid = $validation->is_valid('title');

バリデーションの結果が正しいかどうかをチェックします。もし名前が与えられた場合は、その名前に対応するパラメータが正しいかどうかをチェックします。

add_failed
  $validation->add_failed('title' => 'title is invalid value');
  $validation->add_failed('title');

失敗したパラメーターの名前とメッセージを追加します。もし、メッセージが省略されれば、デフォルトのメッセージが自動的に設定されます。

failed
  my $failed = $validation->failed;

すべての失敗したパラメーターの名前を取得します。

message
  my $message = $validation->message('title');

名前に対応する失敗のメッセージを取得します。

messages
  my $messgaes = $validation->messages;

すべての失敗メッセージを取得します。

messages_to_hash
  my $messages_h = $validation->messages_to_hash;

すべての失敗したパラメーター名とメッセージを、ハッシュリファレンスとして取得します。

2015-11-13

OpenBSDではsrandを使ってrandの再現性が確保できない件

 OpenBSDでは、srandを使ってrandの再現性が確保できないようだ。

 乱数が欲しいとき、言語の標準関数にrandやrandomという名前の関数があればそれを使うのは自然であろう。しかし、Cのrandはランダムではない。むしろ規定されているのはランダムネスではなく、その逆、srandによる予測可能性である。それにも関わらず余りにも多くのコードが定数やpidや現在時刻をシードにして安心しきっている。OpenBSDはPOSIXを破って、そのそうなアホなコードでもランダムになるよう変更を行った。

 今後しばらくOpenBSDでsrandによる再現可能性を必要とする場合にはsrand_deterministicを呼ぶ必要がある (srandのユースケースをすべて調査したあとで元に戻す可能性はあるが)。このような乱暴な手法でセキュリティを実現しようとする独善的態度には批判もありそうだ。

OpenBSD、予測不可能なrand関数を実装(ただしPOSIX違反)

 OpenBSD上におけるPerlのsrand関数もこの影響を受けて、srandとrandを使って、再現性のある試験を書くことができないようだ。