@m_seki の

I like ruby tooから引っ越し

パーフェクトRubyをお中元にいただいた!

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)

著者の一人からお中元にパーフェクトRubyをいただきました。えむさんありがとうございます。
ERBが紹介されていたので蛇足っぽく補足したいです。でも疲れちゃったの途中まで。

bindingを使ったERBの応用

list 11.30はオブジェクトからbindingを取り出していますが、逆にERBオブジェクトをオブジェクトに差し込むこともできます。

require 'erb'

class Something
  attr_accessor :value
  attr_accessor :erb

  def to_s
    @erb.result(binding)
  end
end

something = Something.new
something.erb = ERB.new('value: <%= value%>')

something.value = 'foo'
puts something.to_s

something.value = 'bar'
puts something.to_s

bindingをERBオブジェクトに与えるのは、評価を行う環境を変更するということです。
eRubyスクリプトとその環境についてもう少し考えてみましょう。

eRubyスクリプトは何らかの外部の情報(スクリプトから参照する情報)を用いて文字列を組み立てます。
参照するものが何もなければ静的な文字列を用意すれば済むわけで、当然なことですね。

外部の情報へどのようにアクセスするか、eRubyスクリプトにどうやって情報を与えるのかについていくつかの戦略がありますが、
結局同じような問題に行き着きます。戦略をあげてみましょう。

(1)何もかもeRubyスクリプトに渡す
(2)eRubyスクリプトが必要そうないくつかの情報を集めてきて渡す

前者はすべてをアクセスできるRoot的なオブジェクトを与える作戦です。
Rubyなんで可視性に関する心配は気にせず実利的な問題に関して考えてみましょう。
Root的なオブジェクトから文字列の組み立てに直接必要な情報を取り出す場合、それなりの記述の量となります。こういった情報を取り出す処理をeRubyスクリプトに記述するのは書きにくく読みにくいです。

something.erb = ERB.new("value: <%=
  root.find_all do |x|
    x[3] == 'value'
  end.sort_by do |x|
    x[0] + x[1]
  end.to_a[3]
%>")

根から遠いところにあるオブジェクトにアクセスするメソッドや、検索、並べ替えをするメソッドなど、
そのeRubyスクリプトのための補助的なメソッドが必要になるでしょう。
もちろんなくても記述は可能ですけど、そんなことまでeRubyスクリプトの中で書きたくないですよね。

またフォームやアンカー(リンク)の生成や、文字列の正規化、そしてHTMLのエスケープのような
文字列の組み立てを助けるメソッドもあります。前述のhメソッドなどがよい例です。

... あとでかく。