ブロックを instance_eval に渡す場合、そのインスタンスのコンテキスト内で実行されることを意図しています。selfは、そのブロック内で明示的または暗黙的に参照される場合、instance_eval が呼び出されたインスタンスを参照する必要があります。これは、proc に変換されたメソッド オブジェクトを渡す場合を除いて、すべての場合にうまく機能するようです。この場合、selfは、ブロックが評価されるインスタンスではなく、メソッドが定義されているインスタンスを参照します。私が何を意味するかを示すコード例を次に示します。
class A
def test(&b)
instance_eval(&b)
end
end
class B
def test_a(a)
a.test { puts self }
end
def test_b_helper(*args)
puts self
end
def test_b(a)
m = method(:test_b_helper).to_proc
a.test(&m)
end
end
a = A.new
b = B.new
b.test_a(a) #<A:0x007ff66b086c68>
b.test_b(a) #<B:0x007fa3e1886bc0>
期待される動作は、両方のテストが同じ出力を返すことです。この場合、selfは B ではなく A のインスタンスを参照する必要があります。
ドキュメントを調べていくつか検索しましたが、この特異性に関する情報を見つけることができませんでした。この動作の違いを解決するのに役立つ経験豊富な Rubyist が何人かいることを願っています。
明確にするために、私はRuby 1.9.2を使用しています。