基于BasicObject的Ruby类无法访问其他模块中的代码

时间:2012-06-13 10:50:48

标签: ruby metaprogramming ruby-1.9

我正在使用method_missing为词汇表中的命名空间常量定义一个类。为了有效,我需要从BasicObject继承词汇表类,否则没有一个标准对象方法可用作词汇术语(因为该方法不会丢失:)。但是,当我从BasicObject继承时,我发现我无法在另一个模块中调用实用程序方法。以下代码以压缩形式说明了该问题:

module Foo
  class Bar
    def self.fubar( s )
      "#{s} has been fubar'd"
    end
  end
end

class V1
  def self.method_missing( name )
    Foo::Bar.fubar( "#{name} in v1" )
  end
end

class V2 < BasicObject
  def self.method_missing( name )
    Foo::Bar.fubar( "#{name} in v2" )
  end
end

# this works
puts V1.xyz
# => xyz in v1 has been fubar'd

# this doesn't
puts V2.xyz
# => NameError: uninitialized constant V2::Foo

当我尝试调用辅助模块时,我需要添加到V2以便它不会产生一个整体化的常量错误?

1 个答案:

答案 0 :(得分:3)

如果您更改此V2中的方法,以便在全局范围内开始名称解析,则此方法有效。

def self.method_missing( name )
  ::Foo::Bar.fubar( "#{name} in v2" )
end

我在the documentation for you中查了一下:

  

BasicObject不包含内核(对于像puts这样的方法)和   BasicObject位于标准库的名称空间之外   如果没有使用完整的类路径,将找不到公共类。   ...   可以从Ruby标准库访问类和模块   通过引用所需的常量在BasicObject子类中获得   从类似:: File或:: Enumerator。