CGI::Application::DispatchとMouse(Moose)を使った時にハマったこと
CGI::Application::Dispatchで下記のようにargs_to_newを使うと、
実行するモジュールへの引数が指定出来る。
index.cgi
#!/usr/bin/perl use strict; use warnings; use CGI::Application::Dispatch; CGI::Application::Dispatch->dispatch( prefix => 'Sasakure', table => [ '' => { app => 'Blog', rm => 'posts' }, ], args_to_new => { PARAMS => { foo => 'bar' }, } ); exit;
Sasakure/Blog.pm
package Sasakure::Blog; use strict; use warnings; use base 'CGI::Application'; sub posts { $self = shift; warn $self->PARAMS->{foo}; # エラーログに「bar」が吐かれる。 } 1;
よーし!ディスパッチはできたから、最近かじっているMouseを利用してみよう!
という時に思わぬ事件。。
下記のように書いたらindex.cgiからパラメータが受け取れなくなってしまった。
Sasakure/Blog.pm
package Sasakure::Blog; use base 'CGI::Application'; use Mouse; __PACKAGE__->meta->make_immutable; no Mouse; sub posts { $self = shift; warn $self->PARAMS->{foo}; # そんなんねーよとエラー } 1;
原因はnewにあった。
MooseやMouseで__PACKAGE__->meta->make_immutable;をすると、newというコンストラクタは呼ばれなくなる。
代わりにBUILDという名前のメソッドがその役割を担ようになる。
CGI::Application::Dispatchでは,コールするモジュールのnewメソッドとmode_paramメソッドを実行しようとする。
んで、そのときにargs_to_newで渡されたパラメータを受け取る。
それを1行で済ませるのが、use base qw/CGI::Application/;だ。
継承することで、newメソッドとか書く必要がなくなる。
でも何度も言うようにMouseでmake_immutableすると、、newが呼ばれなくなる。
というわけで下記のように書くことで、無事index.cgiからパラメータを受け取れるようになった。
Sasakure/Blog.pm
package Sasakure::Blog; #use base 'CGI::Application'; use Mouse; # index.cgiからのパラメータをしまう場所を用意 has 'params' => ( is => 'rw', isa => 'ArrayRef[Str]', ); __PACKAGE__->meta->make_immutable; no Mouse; sub BUILD { # newに代わるメソッドでパラメータを受け取る my $self = shift; my ( $dispatch_args, ) = @_; $self->{params} = $dispatch_args->{PARAMS}; } sub mode_param { # これ使わなくても用意しとかないとDispatchがエラー出しよる my $self = shift; return $self; } sub posts { $self = shift; warn $self->params->foo; # 無事、エラーログに「bar」が吐かれる。 } 1;