週末の勉強。
perl 書きな人を「ぱーらー」と勝手に呼んでいますが、
独語で言うなら、私は「die Perlerin(ぱーらりん)」でしょうか。
さて、毎週末は、お勉強タイム。
土日のどちらかは、大きめな本屋に行って
プログラミング関連の売り場をウロウロし、
流行り出した技術のキーワードを拾ってみたり
今仕事で必要そうな技術に関して、立ち読みするのが
ここ5年程の習慣。
そして、改めてアジャイルな本を立ち読みしてたら
「アジャイルプラクティス」は良い本だとシミジミ感じる今日この頃。
リンクしたページからは、教訓的な部分だけPDFファイルで閲覧出来るのだけど
私が普段から思ってる事が沢山書いてあって、
何度も「うん、うん、そうだよね」って思っちゃう。
いやー、他にも、そう感じてる人がいてくれて嬉しいな。
それにしても、今週もいろいろ仕事中に
「これは後で調べてみようかな」と思った事が沢山あったなぁ...って訳で
新しい本や新しい事に手を出している時間はないのでした。
・Catalyst の $c->model が、いやん
MVC構成にちゃーんと作ろうとすると
どう考えても $c->model は違和感ある存在で、
なんで Model 使うのに、$c(Catalystオブジェクト) を介すパターンが出てきちゃったんだろう。
てな訳で、$c->model の説明 を Catalyst.pm で読んでみる。
$c->model($name)
Gets a Catalyst::Model instance by name.
$c->model('Foo')->do_stuff;
Any extra arguments are directly passed to ACCEPT_CONTEXT.
If the name is omitted, it will look for
- a model object in $c->stash->{current_model_instance}, then
- a model name in $c->stash->{current_model}, then
- a config setting default_model, or
- check if there is only one model, and return it if that
s the case. If you want to search for models, pass in a regexp as the argument.
# find all models that start with Foo
my @foo_models = $c->model(qr{^Foo});
sub model {
my ( $c, $name, @args ) = @_;
if( $name ) {
my @result = $c->_comp_search_prefixes( $name, qw/Model M/ );
return map { $c->_filter_component( $_, @args ) } @result if ref $name;
return $c->_filter_component( $result[ 0 ], @args );
}
if (ref $c) {
return $c->stash->{current_model_instance}
if $c->stash->{current_model_instance};
return $c->model( $c->stash->{current_model} )
if $c->stash->{current_model};
}
return $c->model( $c->config->{default_model} )
if $c->config->{default_model};
my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/Model M/);
if( $rest ) {
$c->log->warn( Carp::shortmess('Calling $c->model() will return a random model unless you specify one of:') );
$c->log->warn( '* $c->config(default_model => "the name of the default model to use")' );
$c->log->warn( '* $c->stash->{current_model} # the name of the model to use for this request' );
$c->log->warn( '* $c->stash->{current_model_instance} # the instance of the model to use for this request' );
$c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
}
return $c->_filter_component( $comp );
}
...と言う訳で、とりあえず、Model か M の中にあるオブジェクトは
$c->model(名前) で取得出来ちゃうんだね。
かくして、例えば、MyApp::Model::Anigon なんて作って...
package MyApp::Model::Anigon;
use strict;
use warnings;
sub new { bless {}, $_[0] }
sub get_age { return 37 }
1;
これを Controller ん中で
$c->model('Anigon')->get_age と実行すると
普通に 37 と出るんだね。うーん。
純粋に Anigon->new->get_age って書くのが
自然に出来るようであって欲しかったなぁ、Catalyst。
ちなみに、Catalyst.pm の sub model の
上に実装されているのは sub controller で、
下に実装されているのは sub view。
どちらも $c->controller('名前') や $c->view('名前') で
Controller や C、View や V の配下のオブジェクトを探してくれちゃうってーのも
どーなんだろー...とか思ったり。
それにしても、新人さんと一緒に Catalyst いじってると
今まで知らなかった事が出て来て勉強になるなぁ。
・配列のリファレンスを繋げる
ある日、隣の同僚さんに配列のリファレンスをマージする方法を聞かれて
こうかなぁ...?と試してみたところ、失敗。
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my $array_a = [qw(a b c)];
my $array_b = [qw(d e f)];
my $merge_array = \(@{$array_a}, @{$array_b});
print Dumper $merge_array;
これだと、$merge_array の中は $array_b の中身しか入らない。
おまけに配列のリファレンスだけの話じゃなくて、
こんなんでも同じ現象が起こる。
my $a = 'a';
my $b = 'b';
my $merge = \($a, $b);
print Dumper $merge;
とにかく、\(値) という書き方が、よろしくないらしい。
結局、他の方法で実装してもらったんだけど、
この事を社内ブログに書いたら、別の同僚さんが解決してくれました!
my $merge_array = [@{$array_a}, @{$array_b}];
print Dumper $merge_array;
なーるほどねー。確かにわざわざ \() って書かなくても [] って書けばいいんだよねぇ。
でも、\() を使うと一体何が起きてるんだろう?
はぁー、他にも、いろいろ勉強せなアカン事あるなー。
勉強会もやる事になったから、資料用意せななー。