Apache Velocity。とてもよく出来ているマクロプロセッサです。
個人的に昔から(version1.2あたりから)ずっと愛用している逸品でして、
弊社製品MOD99でも、内部でコレデモカと使いまくってます。
黒歴史
昔、Velocityのソースを魔改造して独自プログラミング言語を作ったことがあります。
カリー化とか高階関数とか、その当時流行った要素を詰め込みまくった「オレオレ言語」だったなぁ。。。( ゚д゚)
いまとなっては黒歴史なダケなんだけど。
その当時、JavaCCの本を買って勉強したものです(VelocityのパーザはJavaCCで書かれている)。
JavaCC関連の和書はコレしかない模様。
- 作者: 五月女健治
- 出版社/メーカー: テクノプレス
- 発売日: 2003/10
- メディア: 単行本
- 購入: 1人 クリック: 9回
- この商品を含むブログ (20件) を見る
文章の言い回しとか章立てとか、ほとんど大学の情報処理系の教科書を読んでいるような感覚。
(まぁ、筆者の方は法政大学の教授なので当然なんだけど)
なんだがとても懐かしい気分に浸れたましたが、とりあえずコンパイラとか処理系の
作り方がわかりました。概論的なトコだけですが。
Velocityは構文木を直接実行するタイプ(Rubyとかもそう)の言語なので、
処理系を作り込むのは比較的簡単でしたねえ。そういや。
さて、
Velocityは1.6になっていくつかのディレクティブを追加してきました。
そのうちの一つが、#defineディレクティブ。
これは、要するにevalみたいなもんです。
#set($one = 1) #set($two = 2) #define($result) #set($three = $one + $two) $three #end $result
の実行結果は
3
です。
ではでは
この実行結果はなんだと思います?
#set($one = 1) #set($two = 2) #define($result) #set($three = $one + $two) $three #end $result #set($one = 'ONE') #set($two = 'TWO') $result
まあオチが見え見えなんですけど。答えは
3 ONETWO
です。要するに#defineはダイナミックスコープになってます。
まとめると、#defineディレクティブの機能とは、
「内部に保持するブロックをキャプチャして遅延評価すること」です。
内部のブロックを評価した結果を格納するわけではありませんので、誤解なきよう。
ちなみに僕は思いっきり誤解してました...orz
Velocityのリファレンスにもそのように明記されてます。
個人的には、ダイナミックスコープって、使い辛いだけだと思うんだけどなぁ。
レキシカルスコープにすればいいのに。
引数渡したいなら、もう既に#macroがあるやんけ。。。