トップレベルでのメソッド定義とSimpleDelegator

たまたまRuby 1.9.2でportupgradeを動かした時に気付いたのですが、以下のコードがRuby 1.8.7Ruby 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