ウェブアプリケーションを書くとき、最近はだいたい Plack::Request なりなんなりを継承して、そのプロジェクト専用のリクエスト/レスポンスオブジェクトを作ることにしている。

特にリクエストオブジェクトは、リクエストのパラメータを適切に変換して返すようなメソッドを生やすことが多い。例えば以下の例:

sub number_param {
	my ($self, $key, $limit) = @_;
	$limit ||= 'inf';

	my $val = $self->param($key) // "";
	if ($val =~ /^\d+(.\d+)?$/) {
		my $ret = $val + 0;
		if ($ret <= $limit) {
			$ret;
		} else {
			$limit;
		}
	} else {
		undef;
	}
}

この number_param() メソッドは、$key と $limit という引数をとって、$key という名前のパラメータを数値にして返す。もし数値として評価できないもの、あるいは指定されていなければ、undef を返す。$limit が指定されている場合、$limit を上限とした数値を返す。

同じように、

sub string_param {
	my ($self, $key, $limit) = @_;
	$limit ||= 'inf';

	my $val = decode_utf8 $self->param($key) // "";
	length $val > $limit ? substr($val, 0, $limit) : $val;
}

と、string_param というメソッドを定義したりしている。これも $key と $limit を引数にとり、$key という名前のパラメータを文字列にして返す。$limit が指定されている場合、$limit 長で制限される。

このようなメソッドをリクエストオブジェクトに生やす利点は、

  • 型を明示することで予期せぬバグを防げる
  • パラメータ値のような信頼できない値を事前にチェックできる
  • 全体で統一した型変換アルゴリズムを設定できる
  • コントローラなどでコードの可読性が向上する

あたりがあると思っている。

文字列化まわりは、フラグまわりでハマったりするので、明確に「これは文字列である」というのをコード上でわかりやすくしたほうがバグが出難いと思う。

数値変換も、ページャを素朴に実装すると、巨大な数字を指定されてほぼテーブルフルスキャンかかっちゃいました、みたいなことが起きたりするので、数値に制限をかけたりするのが簡単にできると捗ると思う。

param() を直接使うのはできるだけ避けるべきだと思う。

  1. トップ
  2. tech
  3. リクエストオブジェクトへ、型を明示するメソッドの追加
▲ この日のエントリ