きりかノート 3冊め

おあそびプログラミング

宿題その1 - eval でメソッドをオーバーライドしても反映されない

MSM2006での宿題 1/2。メソッドキャッシュなのかなあと思って検証。

 require 'osx/cocoa'

class Foo < OSX::NSObject
def foo(sender) 111 end
end

obj = Foo.ocm_send(:alloc).ocm_send(:init)
p obj.ocm_send(:foo, nil).to_i

class Foo < OSX::NSObject
def foo(sender) 222 end
end

p obj.ocm_send(:foo, nil).to_i

出力は

 111
222

と正しく動いている。べつに1回目の呼び出しでキャッシュされてるわけでもなさそう。

でよく考えてみると、eval に渡している binding がマズいのではと気づく。これは TOPLEVEL_BINDING じゃないとユーザの意図した動作にならないのは?

 --- WorksheetController.rb.org	2006-10-22 13:51:26.000000000 +0900
+++ WorksheetController.rb 2006-10-22 13:51:42.000000000 +0900
@@ -28,7 +28,7 @@

def evaluate(sender)
src = @scratchText.string.to_s.gsub(/\r/, "\n")
- result = with_io_redirect { eval(src, $binding) }
+ result = with_io_redirect { eval(src, TOPLEVEL_BINDING) }
@resultText.setString(result.inspect)
@resultText.setTextColor(STD_COLOR)
end

この修正で正しく動くはずで、RubyCocoa の問題ではないです>藤本さん