今日はコールバックの発生順序に関して大はまりしたので個人的に思ったことをメモ。

MTやMTのプラグインから利用可能なコールバックには大きく分けて以下の3つがある。

  • 1) 通常のMTのコールバック(cms_post_saveなど)

  • 2) Data::ObjectDriver(D::OD) が Class::Trigger のトリガーを実行した際に同期して呼ばれる、オブジェクト操作関係のコールバック(MT::Entry::post_saveなど)

  • 3) D::ODが実行する Class::Trigger のトリガー



ちなみに(3)は、以下のように指定/実行できます。

MT::Comment->add_trigger(
post_save => sub {
my $comment = shift;
# do something here...
});


このうち、(1)と(2)はMTのコールバックとして実行されるため、優先順位を指定できるが、(3)はMTのコールバックではないので、どのような順番で処理されるか分からない。そのためドハマリしました。

結局、現在のMTの実装として(恣意的に)


  • Class::Trigger の「pre_****」は常にMTの「pre_****」コールバックより先に呼ばれる

  • Class::Trigger の「post_****」は常にMTの「post_****」コールバックより後に呼ばれる



となっているが、(多分)アンドキュメンテッドな仕様なためこの順序が変更されない保証は無い。ということだと思います。

とりあえずの結論としては、基本的に(3)の方法は使わずに必ず(2)の方法で指定する、必要ならpriorityをきちんと登録する、というのがベストプラクティスなのかなと思いました。


で、ここからが疑問なのだが、単なる数字(MTのコールバックの優先順位は0~11で指定される)では正直何より先or後に実行されるのか分からないんスよね。これって意味有ります?
こういった仕組み自体はよく有る汎用的な仕組みだとは思うのですが。なんか納得いかねえ。

曖昧模糊と「早いうちに」とか「遅い時間に」とか指定するよりも、名指しで「'hoge'プラグインの'mage'コールバックよりは先に実行してください」みたいに具体的に指定できるような仕組みのがベターなのかな、と妄想した一日でした。