HOOK とは、fml8 の内部にあらかじめ用意されている 「小さな perl のプログラムを実行する」 機能です(専門用語でいえば HOOK を eval() するということです)。
HOOK は要所要所に用意されています。
もちろん、HOOK は、そのコンテキストの中で実行されます。 その意味で本質的に危険な機能です。 ある程度、fml8 の中身について理解していないと HOOK を書くことはできません。
その一方、 HOOK をうまく使うことで、 少しの手間で複雑な動作を実現することが可能になります。
ものは使い用です。
HOOK は微妙な修正、もしくは複雑なカスタマイズのために是非必要な機能ですが、 実装においては、いくつかの問題があります。
まず、fml4 の $START_HOOK のような曖昧なものでは、 プログラムごとに異なる動作をさせることが難しい。 たとえば $START_HOOK を設定すると、 配送システムとコマンドメールシステムで同じ $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 の書き方が少々良くなくても動かないと困るでしょう。 というのは「少しだけ修整する」というケースでは、 Perl の素人さんが行なうことも多いからです。
現場では、欲しい機能を実現したい場合、美しいコードを書くことよりも、少 しでも早く実現することが求められます。そこは「美しさ」にこだわるべきで はない点と考えます。
というわけで、通常、各モジュールでは
use strict;になっていますが、 HOOK を評価する lexical scope では無視するようにしてあります。 実際には、HOOK を評価する際に、つねに
no strict; HOOK の内容という構文に変換した上で eval() しています。
fml4 と fml8 の大きな違いのひとつは変数・関数のスコープです。 注意して下さい。 fml4 の関数は全てグローバル関数なので、どんな関数でも使えますが、 fml8 では、そうはいきません。 とはいえ、まったく手がかりがないのも困るので、HOOK が利用できる環境では $curproc オブジェクトだけは常にアクセス可能であることを保証しています。
つまり HOOK を書く際には、 $curproc オブジェクトのアクセスメソッドだけを使って書くようにして下さい。
author's homepage is www.fml.org/home/fukachan/.
Also, visit nuinui's world :) at www.nuinui.net.
For questions about FML, e-mail <fml-bugs@fml.org>.