― Web Technology and Life ―

PerlのAmon2-3.28のLargeフレイバーのDispatherが学ぶべき所が多い

2011-11-23
Perlの凝ったテクニックというかそんなあたりの書き方が凝縮されている気がしたのでゆるーくメモです。

該当コード

『[Amon2入門] Amon2::Setup::Flavor::Large + Teng をもちいた簡単な掲示板の作成 ~ 軽量フレームワークAmon2入門 (7) ~』で紹介されていたから、ちょっとamon2-setupしてみてみた。

    package MyBBS::Admin::Dispatcher;
    use strict;
    use warnings;
    use utf8;
    use Router::Simple::Declare;
    use Mouse::Util qw(get_code_package);
    use String::CamelCase qw(decamelize);
    use Module::Pluggable::Object;

    # define roots here.
    my $router = router {
        # connect '/' => {controller => 'Root', action => 'index' };
    };

    my @controllers = Module::Pluggable::Object->new(
        require     => 1,
        search_path => ['MyBBS::Admin::C'],
    )->plugins;
    {
        no strict 'refs';
        for my $controller (@controllers) {
            my $p0 = $controller;
            $p0 =~ s/^MyBBS::Admin::C:://;
            my $p1 = $p0 eq 'Root' ? '' : decamelize($p0) . '/';

            for my $method (sort keys %{"${controller}::"}) {
                next if $method =~ /(?:^_|^BEGIN$|^import$)/;
                my $code = *{"${controller}::${method}"}{CODE};
                next unless $code;
                next if get_code_package($code) ne $controller;
                my $p2 = $method eq 'index' ? '' : $method;
                my $path = "/$p1$p2";
                $router->connect($path => {
                    controller => $p0,
                    action     => $method,
                });
                print STDERR "map: $path => ${p0}::${method}\n" unless $ENV{HARNESS_ACTIVE};
            }
        }
    }

学ぶべき点

  • 該当のModule::Pluggable::Objectのnewでsearch_path以下のモジュールrequireさせて配列で返してくれる(CPAN本にも載っていた)
  • 「for my $method (sort keys %{"${package}::"}) {...}」で該当パッケージのメソッドを抜いてこれる。(上記コードでは、List::Utilとかエクスポートされたものも入っちゃうのかな?)
  • 「*{"${package}::${method}"}{CODE}」で該当パッケージの該当メソッドのコードリファレンスがとれる
  • 「Mouse::Util::get_code_package($code)」でコードのパッケージ名がとれる。(上記コードでは、これでエクスポートされた関数は無視できるっぽい?)

「for my $method (sort keys %{"${パッケージ名}::"}) {...}」とか全く知らない書き方で、しかも、どいうことで動いているのかよくわかりません。。。ご存知のかたいらっしゃいましたら、参考文献を是非ご教示下さい。。。。

【追記】
「for my $method (sort keys %{"${パッケージ名}::"}) {...}」についての参考情報をコメントでaloelightさんが教えて下さいました!ありがとうございます!これは、該当パッケージのシンボルテーブルを出力する方法なんですねー。シンボルテーブルとかあったなーという感じですが、やっぱり実装でみないと覚えないですねー苦笑。詳しくは『Perl のモジュール (パッケージとシンボルテーブル) 【perldoc.jp】』を参照下さい。

Largeフレイバーのtmpl/[pc|admin]/include/pager.ttもいい

なんかページャーのTTの書き方と以外とめんどいけど、サクっとシンプルに設定されいるのはなんか嬉しい。あと、uri_forとかuri_withとかPOD読んでもイマイチよくピンとこず、わからなかったけど、tmplのサンプルみて、動かしてみてなるほどと思った。一応それもメモっておきます。

uri_with
ハッシュリファレンスで渡したパラメータを、その時リクエストされたURLにつけたいときに使用する。Amon2の場合は、デフォルトですでにあるものは無視してパラメーターを上書きし、オプション{ mode => 'append' }でパラメータの追加モードになる
uri_for
第一引数に相対パス、第二引数にパラメータを渡す。すると、ルート相対パスを生成してくれる。(相対パスは頭がこんがらがる・・・)

もろもろの戯言

最近、「use parent 'Hoge'」ってしたら、HogeにエクスポートされているList::UtilのshuffleとかSmart::Argsのargsみたな関数がHogeの子クラスでuseせずに使えるようにしたいなーと思って、ふわっと、聞いたり調べたりしたんだけど、今さらながらシンボリックとか%INCとか@ISAとか@EXPORTとか名前空間とかなんだったけ?とか、実はrequireのコードとかparentのコードとかExporterのコードとか読んだことなかったと感慨深く思いました。結局、どうすればよいかわからなかったけどw

あと、合わせて読みたい的なネタとしては、『Exporter::Auto ってのつくってみたよ』で紹介している内容とそのコードですねー。Sub::IdentifyとかB::Hooks::EndOfScopeとか、なかなかふーむ、さすが、という感じですねー。

Perl update_at : 2011-11-23T21:50:14
hirobanex.netの更新情報の取得
 RSSリーダーで購読する   
blog comments powered by Disqus