スニペットの仕組み

「ListIndexerやってらんねぇ」とか思いながら、ソースを読んでいる私がいます。OSS陣営の思う壺ですね。
ソースを読んで唖然とするようなことがあったので、昨晩はちょっとエキサイティングでした。

パラメータは無い

スニペットのパラメータ宣言ってどうするんだろう)と思っていたのですが、パラメータは無いことがわかりました。宣言が無いんじゃなくて、パラメータが無いんです。スニペット呼び出しのときに、パラメータらしきものを並べるのですが、あれはパラメータ渡しではありませんでした。スニペット内部の変数に強制代入しているだけだったのです。
なってこったい。

プレースホルダーはグローバルらしい

プレースホルダー」という言葉が説明無しに使われていて眉を顰めていたのですが、昨晩わかりました。MODxはSetPlaceholder()関数を呼ぶ事で、システム内部の特別な連想配列にキーと値を設定できます。プレースホルダーは"[+キー+]"という特別な形式を持つ文字列で、システムは文字列評価時にこの文字列を見つけると、キーに対応する値で置き換えます。つまり文字列マクロ展開なんです。
恐ろしいのは、この文字列評価が実に頻繁に起きる事。文字列代入のようなさりげない操作でも起きるようなのです*1。さらに輪をかけてこの連想配列のスコープや有効範囲がどうやらシステム全体に及びそうなことです。つまり、ある文字列の値は、プレースホルダーにキーをセットする前と後でまったく変わります。スニペットは関数のような振る舞いをするのですが、実行中に副作用を起こすだけではなく、実行後にも副作用を起こすのです。ある種宣言型のシステムと言えます。
すげーや。

*1:自信は無い

/* -----codeの行番号----- */