ウェブアプリケーションを書くとき、最近はだいたい 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() を直接使うのはできるだけ避けるべきだと思う。