― Web Technology and Life ―

Perlモジュールのコードの位置による呼び出し順の違い

2011-08-31
BEGINEとimportの違いに加えて、モジュールの関数外のコード、mainコードにあるコードを加えた順番のメモとHTML::Shakanの使い方の悩み。

呼び出される順番

以下の順番でコードが呼び出されました。

  1. useしたモジュールのBEGINE
  2. useしたモジュールの関数外の部分のコード
  3. useしたモジュールのimport
  4. useしているmainコード

テストコード

#テストモジュール
package Tested;
use strict;
use warnings;

BEGIN { warn 'BEGIN'; }

sub import { warn 'import'; }

warn 'out';

sub new{  bless {noge => 'moge'},+shift; }

sub hoge{
    my $self = shift;
    
    warn $self->{noge};
    
    my $noge = $self->{noge};
    
    warn $self->{$self}->{noge};
}
1;

#実行スクリプト
use strict;
use warnings;
use lib './';
use Tested;

warn 1;

useしたモジュールの関数外の部分のコードはuseされたときに呼び出される

CPANモジュール見ていて、たまに関数外にourとかmyとかいろいろなかたちで変数が宣言されていたりするけど、一体どのタイミングで呼び出されるのかなーと簡単にテストしてみたら、こうなりました。個人的に、importの方が先だと思っていたので、調べてみてよかった。useされたときに一度だけ呼び出されるから、なんとなくメモリキャッシュな感じで便利な使い方ができます。

【追記】
karupaneruraにご指摘頂いたとおり、正確には、useではなくrequireされたときということです。参考→use 【perldoc.jp】。ちょっとずれますが、useとrequireの違いって、いつ呼び出されるかだけだと思っていたんですが、requireだとimportが呼ばれないんですねー。勉強になります!

リクエストのたびにモジュールの関数外の部分のコードを呼び出したい

ふと、このブログで使っているこのKamui::Container経由で呼び出しているHTML::Shakan::Declareコードが、DBからデータ引っ張ってきて動的にフォーム項目を生成しているんだけど、なんでこれがうまく動いているのかよくわからなくなりました・・・。

package Hirobanex::Api::Form;
use strict;
use warnings;
use utf8;
use Hirobanex::Container qw/api/;
use Encode;
use HTML::Shakan::Declare;
use HTML::Shakan::Model::DBIxSkinny;

sub new { bless {}, +shift }

my $tag_choices = [map { ($_->tag) x 2 } @{api('BlogCategory')->fetch_list}];
.
.
.
    ChoiceField(
        name => 'category_tag1',
        label => 'Category_Tag1:',
        required => 1,
        choices => $tag_choices,
    ),
.
.
.

HTML::Shakan::DeclareはDSLで書くから、そのあたりで上手いこと読み取ってくれるのかな?Kamui::Containerは毎回コードのコンパイルから走らせるのかな?とか思って調べてみたがまったく違う。

よくよく確認したら、開発環境でつかっていたplackupコマンドの「-L Shotgun」オプションが本番でも有効だったからです。

plackup -L Shotgun

以下の記事を参考にすると、

「plackup -L Shotgun」は、リクエスト毎に使用しているモジュールの再コンパイルから行うということで、「MooseとかDBIx::Classとかコンパイルに時間がかかるモジュールをいれてやってはいけないよ」、とも書かれてますw。

結論ですが、「リクエストのたびにモジュールの関数外の部分のコードを呼び出したい」場合は、それほどモジュールのロードに時間がかからず、対してレスポンスに対する制限が厳しくないのであれば、気軽に「plackup -L Shotgun」を使いましょうということです。(毎回コンパイルからはしるので、別にBEGINとかimportとかに書いてもいんですが・・・)

終わりに

まぁ、それでも、やっぱりリクエスト毎にコンパイルとかありえないようなーということもあるので、上で例に挙げたぼくのブログのコードの場合は、HTML::ShakanのChoiceFieldを独自で実装して、、、、と思ったけど、Fieldのところってプラガブルになっていったっけなー。。。どうしよ。。。とりあえず、Shakanのコードとドキュメントをチェックしなおしたいと思いますが、何かいいやりかたご存知のかたいらっしゃったら教えていただけるとうれしいですっ!

Perl update_at : 2011-09-16T12:50:02
hirobanex.netの更新情報の取得
 RSSリーダーで購読する   
blog comments powered by Disqus