マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

テンプレート的 LaTeX、再び (3)

前回の続き)

ところで、templatex の実装(というよりテンプレートエンジン ixsst の実装)は ERB の処理方法をそのまま真似ている。ERB で同様の例を試してみた。

<%def test(n)
  1.upto(n) { |i| %> (<%=i%>) <% }
  end %>
<% test(5) %>

これを実行するとエラーが出る。

test.erb:2:in `block in test': undefined local variable or method `_erbout' for
 main:Object (NameError)
        from test.erb:2:in `upto'
        from test.erb:2:in `test'
 ……(後省略)……

erb -x」でコードを出力してみると……。

_erbout = ''
def test(n)
  1.upto(n) { |i|
    _erbout.concat " ("
    _erbout.concat(i.to_s)
    _erbout.concat ") "
  }
end
_erbout.concat "\n"
test(5)
_erbout.concat "\n"

構造的には Lua のコードとほぼ同じだけど、Ruby のローカル変数のスコープのルールでは、外で定義したローカル変数 _erbouttest 関数の中では見えない、ということのようだ。

とすると、ERB では、関数の中で何らかの出力をしようと思ってもその術がないということか。*1気付かなかった……。

ちなみに、PHP で同様の構造は平気に動作する。実際に使われることも多いであろう。

<?php
function test($n) {
  for ($i = 1; $i <= $n; $i++) { ?> (<?php echo $i ?>) <?php }
}
?>
<?php test(5) ?>

(出力)

 (1) (2) (3) (4) (5)

*1:そんなコードの書き方は汚いからやめておけ、てことかも知れない。