@m_seki の

I like ruby tooから引っ越し

言い訳

なぜ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でしてましたとさ。まあ与太話ですな。もうちょっと深い話をしたんだけど、書くのも飽きてきた。そうしたくなっちゃうのは一緒に作ってる相手を信用しないからかなあ、とかだったっけ?