HOOK
概要もしくは HOOK における諸問題
hook は微妙な修正、もしくは複雑なカスタマイズのために是非必要です。
ですが、実装においてはいくつかの問題があります。
まず、&fml4; の $START_HOOK のような曖昧なものではなく、
hook の名前に一定の基準が必要でしょう。
そのため &fml8; では、ある関数の最初と最後にHOOKを用意する場合、
次のようなスタイルの HOOK 名称になっています。
$役割_関数_start_hook
$役割_関数_end_hook
これにより配送システムとコマンドメールシステムで共通の HOOK などという
ものはなくなり、別々のHOOKをしかけることができるようになります。逆に、
共通のものをしかけようとするなら、一杯書いて下さい;)ということです。
まぁコピーすればいいだけだから、さして難しくないですよね?(と思いたい)
$distribute_XXX_start_hook = q{ ... };
$YYY_XXX_start_hook = $distribute_XXX_start_hook;
また、HOOK の書き方が少々良くなくても動かないと困るでしょう。
通常、各モジュールでは
use strict;
になっていますが、HOOK を評価する lexical scope では無視するようにして
あります。
実際には、HOOK を評価する際に、つねに
no strict;
HOOK の内容
という構文に変換した上で eval() しています。
&fml4; と &fml8; の大きなちがいのひとつは変数、関数のスコープです。
&fml4; はグローバルなので、どんな関数でも使えますが、&fml8; では、そう
はいきません。とはいえ、まったく手がかりがないのも困るので、$curproc
が使えるような場所にのみ HOOK を用意するといったルールが必要でしょう。
いまのところ、そういう方針になっています。
hook の命名規則
hook 名前の標準的な形式については
役割名_メソッド名_start_hook
役割名_メソッド名_end_hook
などとすることにしました。ここで役割名は「use_XXX_function」(例:
use_article_post_function)のXXX部分です。もっと粒度の細かいHOOKについ
ては、この形式でないものもあります。
たとえば、fmlconf コマンドのメインの部分 run() の HOOK の名前は
fmlconf_run_start_hook
fmlconf_run_end_hook
となり、run() の中での hook 呼び出しは次のようなコードになります。
sub run
{
my ($curproc, $args) = @_;
my $config = $curproc->{ config };
my $eval = $config->get_hook( 'fmlconf_run_start_hook' );
if ($eval) {
eval qq{ $eval; };
print STDERR $@ if $@;
}
$curproc->_fmlconf($args);
$eval = $config->get_hook( 'fmlconf_run_end_hook' );
if ($eval) {
eval qq{ $eval; };
print STDERR $@ if $@;
}
}
現実にはもっといろいろな場所に HOOK がないと不便でしょうが、
その名前は上述の HOOK 以外に設定します。
単純に hook2 でいいのかもしれないし、
可能であればもう少し理解しやすい名前にするべきでしょう。