インタープリター型のテンプレートエンジン
こんばんは。帰りにコンビニに乗って、ついつい甘いものを買ってしまう。
今日も買ってしまいました。
ファミマのスイーツって結構美味しくて、でも結構高いんでね。
あーと思いながら、まあでも、今日も仕事頑張ったしいいかということで、買ってしまいました。
gawkの話をまたしていきます。
今日はテンプレートエンジンについてです。
私の作ってるgawkのwebアプリケーションのテンプレートエンジンはですね、
作り直してて、2回か3回ぐらい作ってるんですけど、
今日は話すのは、2種類のテンプレートエンジンの話をします。
一番最初というか、覚えてる限りで先に作ってたのが、
プログラムのインタープリター、言語処理系のインタープリターに近いような、
ここではインタープリター型って呼ぶことにするんですけど、
そういうテンプレートエンジンで、後に作って作り直したのが、
コンパイラーに近いというか、コンパイル型というふうに呼ぶことにします。
というテンプレートエンジンでした。
Webアプリケーションのここでいうテンプレートエンジンっていうのは、
何らかのテキストで示されたテンプレートっていうのと、
あとはそこに埋め込む変数の値みたいなものを受け取って、
後にHTMLのテキストを生成するっていうのがやることになります。
一番最初に作ってたインタープリター型のテンプレートエンジンは、
結構素朴に作っていて、あるテンプレートを読み始めたら、
それをパターンマッチで特定のパターンが出てくるまで読むと。
それを読んだら、すぐにそこまで分かる結果のHTMLのモジュレートを詰めていくというか、
いわゆるトークナイズとかパースとかコードジェネレーターとかが分かれてなくて一体となってるような作りだったんですね。
結構それには制約があって、途中まで読んだところ戻りたいとか、繰り返しみたいなのを実装するのは結構大変なんですよね。
最初素朴に作っていたので、繰り返しみたいなやつはもうファイルを分けちゃって、
もう一回ファイルを最初から読むと、フォーみたいな構文はサポートしてなくて、
インクルードフォーみたいな構文にしておいて、5回繰り返したいなら5回ファイルの中を読むみたいなのを実装してたんですね。
処理速度とかはそんな大きいアプリケーションじゃないんで気にならないんですけど、
やっぱり書き心地が良くなくて、テンプレートってそこそこ具体的ないろんなパターンを書くので、
いちいちファイルを切り分けてたりしたらめんどくさいんですよね。
なので、あんまり気に入らなくて、結局それは捨てちゃいました。
コンパイラー型のテンプレートエンジン
今考えれば、パーサーみたいなのを作って、一度連想配列にパースした結果を入れておけば、
コード生成をもう1回上から舐めていくみたいにすれば、それもぼちぼち使えたんじゃないかなと思うんですけど、やめてしまいました。
乗り換えて、今はコンパイル型というふうに私が呼んでるテンプレートエンジンにしています。
これはどういうものかっていうと、テンプレート、例えば10種類とか20種類とかあるテンプレートっていうのを受け取って、
それを1つのOrgプログラムにコンパイルしてしまうっていうものです。
この方式のテンプレートエンジンっていうのは、結構シンプルに強力な機能を提供できて、
テンプレートエンジンなんか本当にシンプルなんですね。
一番最初にOrgのプログラムとして関数のレンダーっていう、レンダーみたいな感じの名前にしたんですけど、
関数の1000弦と、あとはスイッチ分のスイッチみたいなものを書いて、
その後、たくさんのファイルの処理を受け付けると。
1ファイルにつきそのファイルの中を読んで、それを1つのケース分として文字列を埋め込むみたいなOrgのプログラムを出力するコードを書きます。
こうすると、例えばforみたいなのとかifとか、そういう複雑な制御構文っていうのは、
全部Orgのそういう複雑な制御構文をプリントさえすれば、Orgのランタイムの処理っていうのを使えるので、
あんまり考える必要がないんですね。
なので、一番前からテンプレートっていうのを読んでいって、
特定のパターンにマッチしたら置き換えるみたいなことを書いていくだけで、
すごいシンプルに数授業とかそういう感じのプログラムでめちゃくちゃ複雑なことができると。
そういうふうにしています。
この一番最初に話していた、インタープリタカだとコンパイルだとみたいな2つの区分けっていうのは、
テンプレートのユースケースによって許可されるシーンが全然違うなっていうふうに思いました。
というのは、そのテンプレートを誰が書くかで、
アプリケーションの開発者自身がテンプレートを書くっていう場合は、
どちらでもそんなに問題にならないっていうふうに思うんですけど、
ユーザーに提供する場合っていうのは、
後者のコンパイラー型っていうようなテンプレートというのは結構使いづらいというか危険というか考えることが多いんじゃないかなっていうふうに思います。
ユーザーが書いたテンプレートっていうのがコードにコンパイルされるわけですし、
そのコードが放送しているウェブアプリケーションと同じ実行権限でファイルとして組み込まれて動くと。
なんでサンドボックスにもなっていないし、結構扱いづらいわけですね。
そこを何かしら分けてあげるインターフェースなんていうか境界がないと、
セキュリティリスクにもなりうるし大変だなっていうふうに思います。
これは今回作ったテンプレートエンジンに限らず、
いろんなテンプレートエンジンに、世の中のテンプレートエンジンに言えることじゃないかなっていうふうに思います。
開発者向けのテンプレートエンジンとエンドユーザー向けのテンプレートエンジン。
そんな区分けができるんですかね。
とはいえですね、私のZiookのアプリケーションでは、
少なくとも今のところ開発者である私がテンプレートを書くユースケースしかないですし、
本当にすごい短いテンプレートエンジンのコードで豊富で、
いわゆる普通のテンプレートエンジンでありそうな表現というのは結構できるので、
面白いというか、こんなんでいいんだっていうのは結構発見でした。
いくつかある実装の中でも結構好きな部分というか、やっぱりテキスト処理は得意ですね。
単純なテキスト処理は得意なんで、多分他のプログラミング言語で書くよりも多くで書いていて、
短く簡潔に書けてる部分があるコードなんじゃないかなということで結構好きです。
というわけで今日はこの辺りにしておきたいと思います。
ではまた。