Hatena::ブログ(Diary)

Scrapcode@はてなダイアリー このページをアンテナに追加 RSSフィード

2010-02-03

NanoAでモバイルサイト(4) - app/myapp/config.pmの書き方

また前回から大きく時間が開いてしまいました。

NanoAはもう長い間更新されていないし、今更NanoAの記事を公開してもあまり意味がないかな…とか思いつつ、下書きに書きかけの記事がいくつかあったので、そのうち一つを完成させて公開してみます。

今回は app/myapp/config.pm の書き方です。今回もモバイルサイトとは特に関係ありません。

NanoAプラグインについての説明に、このような記述があります。

また、myapp/config.pm 内で use pluginname; すれば、同ディレクトリ内の全コントローラプラグインが適用されます。例えば、全コントローラモバイル対応機能を有効化したい、という場合は、こちらの手法が便利です。

no title

app/myapp/config.pm について簡単に記述されていますが、具体的にどう書けばいいのかが書かれていません。

正しい書き方を調べるために、まずはどういうタイミングで app/myapp/config.pm が呼び出されるのかを見てみます。

nanoa.cgiでconfig.pmを検索してみると、NanoA::Dispatchのload_config内に見つかりました。

sub load_config {
    my ($klass, $handler_path) = @_;
    my $app_name = $handler_path =~ m|^(.*?)/| ? $1 : 'system';
    my $module_name = "NanoA::Config";
    if (NanoA::load_once(NanoA::app_dir() . "/$app_name/config.pm")) {
        $module_name = "$app_name\::config";
    }
    return $module_name->new({
        app_name => $app_name,
    });
}

if文のところで app/myapp/config.pm の読み込みを試してみて、成功した場合はmyapp::config、それ以外はNanoA::Configのインスタンスを生成しています。このことから、myapp::configはNanoA::Configを継承させておくべき、ということがわかります。

これを踏まえて、app/myapp/config.pm を作ってみます。

package NanoA;

use plugin::myplugin;  # <- プラグイン呼び出し


package myapp::config;

use strict;
use warnings;
use utf8;

use base qw{ NanoA::Config };

1;

これで、myappで共通で使用するプラグインの呼び出しができるようになりました。

ところで、上記コードではプラグイン呼び出しの前にNanoAパッケージを宣言しています。これをしないと、plugin::mypluginのinit_pluginに渡される第2引数が 'myapp::config' になってしまうからです。

NanoA付属のプラグインを見ると、例えば app/plugin/form.pm ではinit_plugin内で第2引数($controller)を使用してコントローラオブジェクトにメソッドを追加しています。もし上記 app/myapp/config.pm でNanoAパッケージに切り替えずにmyapp::configパッケージ内でuse plugin::myplugin;してしまうと、formプラグインが追加するメソッドはmyapp::configのメソッドになってしまいます。

プラグインによるメソッドの追加方法がinit_plugin内ではなく、sub NanoA::method { ... } のように直接NanoAパッケージを指定して追加している場合は、myapp::configパッケージ内で use plugin::myplugin しても大丈夫です。

なお、これらの場合は厳密には実行されるコントローラのパッケージではなくNanoAパッケージにメソッドが追加されることになります。コントローラのパッケージはNanoAパッケージを継承させるので、NanoAパッケージに追加されたメソッドも他で上書きされなけば、コントローラ側で同じように使えます。

初期化処理の書き方

プラグイン呼び出し以外にも、共通で行いたい初期化処理もあります。その場合はNanoA::Configで用意されているinit_appをオーバーライドします。

package myapp::config;

use strict;
use warnings;
use utf8;

use base qw{ NanoA::Config };

sub init_app {
    my ($self, $app) = @_;

    # ここに初期化処理を記入
}

1;

$appには、その実行時のコントローラオブジェクトが入ります。なので、ほぼ共通だけど一部のコントローラでは共通の初期化処理を適用したくない、というような場合には、次のようにすれば良さそうです。

package myapp::config;

use strict;
use warnings;
use utf8;

use base qw{ NanoA::Config };

sub init_app {
    my ($self, $app) = @_;
    my $control = ref $app;

    if( $control ne 'myapp::start' ) {
        # myapp::start 以外の共通処理
    }
}

1;

または、各コントローラ全てで共通処理の要・不要を返すメソッドを用意しておいて、それを呼び出して判断します。

package myapp::config;

use strict;
use warnings;
use utf8;

use base qw{ NanoA::Config };

sub init_app {
    my ($self, $app) = @_;

    if( $app->need_session ) {  # <- セッション処理が必要な場合に真を返すメソッド
        # セッションの前処理
    }
}

1;

コントローラ

package myapp::xxx;

use strict;
use warnings;
use utf8;

# セッション処理が必要なコントローラでは真を返すようにする
sub need_session { 1 }

1;

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/khashi/20100203/1265187346