Mojoliciousのプレースホルダでドットを含むパスをキャプチャしたくない時の話。

全然別のタイトルで記事書いたのですが、内容が間違いまくってたのと愚痴っぽくてひどかったので消しました。30分位で消したから多分誰も見てないんじゃないでしょうか。

Mojoliciousの通常のプレースホルダはドットとスラッシュをキャプチャせず、含んでいた場合はルーティングに失敗します。が、その挙動を期待していたのに、ルーティングに失敗せずに200OKを返してしまうパターンがあってはまりました。
具体的に言うと、/standard/:nameのようなルートを設定していた場合、/standard/hello.htmlとか、hello.jsonのようなパスを設定されると、普通に200OKが返ってしまいます。
タチが悪いことに、param(‘name’)の値はhelloを返すので、paramの値で分岐するようなコードにしてると、意図しないルートをガード出来てないことになかなか気づきません。
具体例は以下。Perlはv5.16.3、Mojoliciousはv7.05です。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;

use Mojolicious::Lite;

# リラックスプレースホルダ
get '/relax/#name' => sub{
        my $self = shift;
        return $self->render(json =>{param => $self->param('name'), format => $self->stash('format')});
} => 'r';
# /relax/hello.json:
# {"param":"hello.json","format":null}

# 普通のプレースホルダ
get '/standard/:name' => sub{
        my $self = shift;
        return $self->render(json =>{param => $self->param('name'), format => $self->stash('format')});
} => 's';
# /standard/hello.json: 
# {"format":"json","param":"hello"}

# 普通のプレースホルダ+format無効化
get '/standard_disable_format/:name' => [format => 0] => sub{
        my $self = shift;
        return $self->render(json =>{param => $self->param('name'), format => $self->stash('format')});
} => 'sd';
# /standard_disable_format/hello.json:
# status:404

普通のプレースホルダでドットを含んだ値を絶対キャプチャしたくない場合は、[format => 0]を指定しようと思いました。
MojoliciousとかMojolicious::Lite側の仕様は以下。
Mojolicious::Guides::Routing – Routing requests
Mojolicious::Lite – search.cpan.org

splapiはいろいろあってこのルートはガードする必要があるので、v1.12で修正しています。