Python で eRuby を実現するには

インデントベースだとeRubyのようなテンプレートが難しい

Matz日記:PythonをDISる

Python はインデントベースなので、eRuby に限らずコード生成とは全般的に相性が悪い。しかし、eRuby 程度であれば以下のようなルールで実現できる。

  • テキストを print 文 (またはそれに相当するもの) に変換するときは、
    • 直前の文が「:」で終わっていればインデントを増やす
    • それ以外なら直前の文やコメントと同じインデントを使う
  • for 文や if 文の終わりは、インデントしたコメントで明示するようにする。


たとえば次の例では、2 行目が「:」で終わっている。そのため、変換された Python コードの 3 行目では、インデントを増やしている。また 5 行目のインデントが戻っているのは、直前 (4 行目) のコメントのインデントに合わせているためである。

### もとのテキスト
1: <ul>
2: <% for item in L: %>
3: <li><%= item %></li>
4: <% #end %>
5: </ul>

### 変換された Python コード
1: print "<ul>",
2: for item in L:
3:     print "<li>", item, "</li>"
4: #end
5: print "</ul>"


次の例では、4 行目は「:」で終わってはいない。そのため、変換された Python コードの 5 行目では直前の 4 行目と同じインデントを使っている。

### もとのテキスト
1: <ul>
2: <% i = 0 %>
3: <% for item in L: %>
4: <%     i += 1 %>
5: <li><%= i %>:<%= item %></li>
6: <% #end %>
7: </ul>

### 変換された Python コード
1: print "<ul>",
2: i = 0
3: for item in L:
4:     i += 1
5:     print "<li>", i, ":", item, "</li>"
6: #end
7: print "</ul>"

Makoもそうですが、end明示するのは「工夫」とは言えないのでは。

Matz日記:PythonをDISる

eRuby のようなツールでは、Python のインデント方式は利用できない。
また eRuby と同じようにテキスト汎用にしようとすると、for 文や if 文では「範囲」を指定しなければならず、どうしても「end」のようなものが必要になる。
だから、Mako や pyTenjin で「end」をつけるのは、工夫ではなくて「必然」(あるいは「必要悪」) といえる。

このへんは、確かに Python と eRuby もどきは相性が悪いと言えるが、「end」をつけるだけで回避できるのであれば、そう大きな欠点ではないと思う。