なぜERBにパラメータつきのevalがないのか、某氏に説明した。書けば書けるんだけど。たとえばこんなのを本体にいれてもいい。
require 'erb' class ERBEnv def initialize(hash) @_erb_env_ = hash end def evaluate(erb) erb.result(binding) end def method_missing(msg, *arg, &blk) @_erb_env_.fetch(msg) rescue IndexError @_erb_env_.fetch(msg.to_s) end def self.evaluate(erb, hash) self.new(hash).evaluate(erb) end end
パラメータをHashで渡すとして、keyがSymbolやString以外の可能性もあるし、文字列風なkeyであっても変数名(メソッド名?)として有効かどうか検査するのがめんどくさいのでmethod_missingで引くことにした。
アプリケーションはどうなるのかな。
erb = ERB.new(<<EOS) <%= a %>, <%= b %> EOS hash = {:a => 'Hello', :b => 'World'} puts ERBEnv.evaluate(erb, hash)
hashをつくるところが微妙にださい。テンプレート評価器の一般的な評価メソッドとしてはしょうがないんだけど、アプリケーション全体で見るととほほな感じがする。だってさ、実アプリケーションだと、パラメータはもっと豊富にあるだろうから、hash組み立てメソッドを書かざるをえない。いろんな作戦があるだろうけど、たとえばこんなの。
class MyView def make_view_arg(foo, bar, baz, .... ) hash = {:foo => foo, :bar => bar, :baz => baz, ....} end def to_html(foo, bar, baz, ....) hash = make_view_arg(foo, bar, baz, ...) ERBEnv.evaluate(ERB.new(...), hash) end ... end
あるいは
def to_html hash = make_view_arg(get_foo, build_bar, calculate_baz, ...) ERBEnv.evaluate(ERB.new(...), hash) end
とかさ。だったら
def to_html(foo, bar, baz, ...) ERB.new(...).result(binding) end
の方がシンプルなのに。このスタイルになったら、そのままdef_methodできるしさー。とか、そういうつまんない話を某ircでしてましたとさ。まあ与太話ですな。もうちょっと深い話をしたんだけど、書くのも飽きてきた。そうしたくなっちゃうのは一緒に作ってる相手を信用しないからかなあ、とかだったっけ?