トップレベルでのメソッド定義とSimpleDelegator
たまたまRuby 1.9.2でportupgradeを動かした時に気付いたのですが、以下のコードがRuby 1.8.7とRuby 1.9.2とで挙動が異なります。
require 'delegate' def foo :foo end class A < SimpleDelegator def initialize @obj = [] super(@obj) end def bar foo end end p A.new.bar
Ruby 1.8.7の場合:
% ruby -v c.rb ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0] :foo
Ruby 1.9.2の場合:
% ruby192 -v c.rb ruby 1.9.2p271 (2011-05-31 revision 31856) [x86_64-darwin10.7.0] c.rb:14:in `bar': undefined local variable or method `foo' for []:A (NameError) from c.rb:18:in `<main>'
portupgradeではlib/pkgtools.rbでユーティリティ的メソッドがトップレベルで定義されていて、各クラス内から呼び出されている模様。そのためふいに上記例外が発生してしまいます。この挙動の違いが正しいかどうかすらわかってないので、どのように対処して良いものか悩むので、忘れないうちにメモっておきます。
2011-06-13 追記
トップレベルで定義しているメソッドをKernelモジュール内で定義するようにすればいけるようです:
require 'delegate' module Kernel def foo :foo end end class A < SimpleDelegator def initialize @obj = [] super(@obj) end def bar foo end end p A.new.bar
こんな感じ:
% ruby192 e.rb ruby 1.9.2p271 (2011-05-31 revision 31856) [x86_64-darwin10.7.0] :foo