読者です 読者をやめる 読者になる 読者になる

初代Masteries

きっとモヒカンにもなれないお前たちに告げる!!!

Perl入学式#11でいろいろ学んできた

12月15日開催のPerl入学式 #11に参加してきました.
今回は@先生によるMojolicious::Lite講座の最終講義で, 一応サポーターとして参加していたはずなんですがいろいろと質問したりコード書いたりしていて, 最終的には参加者っぽくなっていました.

その中で, 「renderやredirectの後にはreturnが必要」という話があったのでちょっとメモを残しておきます.
確かDMTCの準備としてMojolicious::Liteの復習してた時に一瞬詰まったりしていたので, 再び間違えないように...


renderやredirectはあくまで「どのテンプレートを描画するか/どのページにリダイレクトするか」という予約するだけで, その時点でその動作を行う訳ではない.
「実行された時点でそれらの動作が行われる」と思っているとこんなコードを書いてしまって, とてもマズいことになる.

get '/' => sub {
    my $self = shift;

    ...

    $self->render('hoge') if $hoge;
    $self->render('fuga');
};

$hogeが真の場合テンプレート'hoge'が, それ以外の場合はテンプレート'fuga'が呼び出されるように書いたつもりだけど, この場合は常にテンプレート'fuga'が呼び出されてしまう.

これは, 冒頭にも書いた通りrenderやredirectは「予約」をするだけで, 複数のrenderやredirectがあれば, 一番最後のもので予約が上書きされてしまうから(この場合, $hogeの真偽にかかわらず, 常に$self->render('fuga')が実行されて, 「予約」が上書きされてしまう).
よって, こういう場合は

get '/' => sub {
    my $self = shift;

    ...

    return $self->render('hoge') if $hoge;
    return $self->render('fuga');
};

このようにreturnを入れてあげればOK.