安全なERB

この記事は筆者が見た夢を一人称視点で叙述した内容です。事実ではなく、実際の人物等とは一切関係ありません。

ERB を Web アプリケーションのビューに使うときなんかに、変数とかを使うときによく考えないと、余計なメソッドを呼ばれたり、めんどうなので。

def render_erb(template, vars={})
  require "erb"
  obj = Object.new
  obj.class.instance_eval do
    vars.each do |(k, v)|
      define_method(k) { v }
    end
  end unless vars.empty?
  obj.instance_eval do
    ERB.new(template).result(binding)
  end
end

stash = {
  :user => "aereal"
}

template = <<EOF
You logged in as #{user}
EOF

puts render_erb(template, stash) # => "You logged in as aereal"

新しいオブジェクトを作ってそれにメソッドを定義してやる。新しい binding になるのでメソッド名の重複とか考えなくていい…はず。
1.9になると BasicObject というのが導入されるようなので、1.9なら BasicObject を使った方がより安全だとおもう。たぶん。