Diary of Sacred Fox - May 05, 2009

The Quintetには通算 179068 人(今日:0, 昨日:1)のお客様が来場しています

2009/05/05(1)

perlのAutoLoader, AutoSplitを使ってみる

自作Perlモジュールで, 常に全体をコンパイルするのは勿体無いという人用, ある種のJIT的な動作になる
使うには以下のようにコードを変更する

  1. use AutoLoader qw(AUTOLOAD); する
  2. 自動ロードの対象にする関数群をソースの一番下に移動する
  3. 自動ロードする関数群の直前におもむろに __END__ を置く, これでこれらはモジュールのロード時には読み込まれなくなる
    当然 __END__ の直前には1;と書いてモジュールが読めるようにしておくこと
  4. AutoSplitでコメントアウトした関数定義をAutoLoaderが読めるように別ファイルに書き出す, デフォルトルールに以下の内容を書いたMakefileを置いておくといいかも
    find . -name \*.pm -print0 | xargs -0 -I_ perl -MAutoSplit -e 'autosplit q(_), q(auto);'

これで任意の関数をモジュール本体から分離できる
存在しない関数名を叩いたときのエラーがAutoLoaderのものになるが, それ以外は普通に使えるはずである
以下, tipsと注意点

Comments (1):

  • Sacred Fox: 下のほうに書いたけど, SelfLoaderのほうが便利である (05/05 15:46)

2009/05/05(2)

perlでプラグイン機構的なものを作る

まぁやり方はこれがperlのperlたる所以色々あるだろうけど, 以下に一例

use strict;
use warnings;
# 引数: モジュール名
# 返値: モジュール名 or 空リスト(失敗時)
sub load_module($) {
  my $mod = shift;
  return eval "require $mod;" ? $mod : ();
}
# 引数: モジュール名のプレフィックス
# 返値: モジュール名のリスト
sub load_modules($) {
  my $modprefix = shift;
  my @modlist;
  (my $moddir = $modprefix) =~ s/::/\//g;
  opendir my($dir), $moddir;
  foreach my $mod (readdir $dir) {
    next unless $mod =~ s/^(.+)\.pm$/${modprefix}::$1/;
    push @modlist, load_module $mod;
  }
  closedir $dir;
  return @modlist;
}
# 実行例
foreach my $mod (load_modules 'plugins') {
  print $mod->name(), "\n";
}

こんな感じで後はモジュール名についてforeachまわしたりとか, ロード時にinit()でコールバックを登録させるようにしたりとか, 好きに出来そうである

Comments (0):

2009/05/05(3)

perlのSelfLoaderを使ってみる

s/AutoLoader qw(AUTOLOAD)/SelfLoader/; s/__END__/__DATA__/;
AutoSplit呼ぶ必要もないし, こっちのほうが便利そうである
デバッグ時に __DATA__ をコメントアウトする手法は問題なく使える, 末尾にダミーの __END__ や __DATA__ も要らないみたいである
なんで最初からこっちを使わなかったんだろうか… > 昨晩の自分
当然だけど __DATA__ を使うプログラムでは読む順番とかに気をつけないとひどい目に遭うはず
…けど, そんなものを使おうと思ったことは今まで1度も無いからいいや

また, AutoLoaderと違ってサブルーチンスタブは生成してくれないので, 引数チェックを行いたければ SelfLoader->load_stubs(); を __DATA__ の前においておく必要がある模様, これをやるとデバッグ時にもダミーの __DATA__ が要るみたいである
…でも, これも use strict や use warnings みたいにデバッグ中だけ有効ならそれで十分な代物かもしれない
ただし, 継承とかを使う場合は必須らしい

AutoLoaderとの性能面での得失は perldoc SelfLoader に書いてあるが, 以下の通り

Comments (0):