简体   繁体   English

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

[英]Ruby class based on BasicObject can't access code in other module

I'm using method_missing to define a class for namespacing constants in a vocabulary. 我正在使用method_missing来为词汇表中的常量常量定义一个类。 To be effective, I need the vocabulary class to inherit from BasicObject , otherwise none of the standard object methods are available as vocabulary terms (because the method isn't missing :). 为了有效,我需要词汇表类从BasicObject继承,否则,没有标准的对象方法可用作词汇表项(因为该方法没有丢失:)。 However, when I inherit from BasicObject , I find I can't call utility methods in another module. 但是,当我从BasicObject继承时,我发现无法在另一个模块中调用实用程序方法。 The following code illustrates the issue in condensed form: 以下代码以简洁形式说明了此问题:

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

What would I need to add to V2 so that it doesn't produce an unitialized constant error when I try to call the helper module? 我需要在V2添加些什么,以便在尝试调用helper模块时不会产生统一的常量错误?

It works if you change the method in V2 like this so that name resolution starts in the global scope. 如果您像这样在V2更改方法,则该方法将起作用,以便名称解析在全局范围内开始。

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

I looked it up in the documentation for you : 我在文档中为您查找了它:

BasicObject does not include Kernel (for methods like puts) and BasicObject is outside of the namespace of the standard library so common classes will not be found without a using a full class path. BasicObject不包含内核(用于puts之类的方法),并且BasicObject在标准库的命名空间之外,因此,如果不使用完整的类路径,将找不到常见的类。 ... Access to classes and modules from the Ruby standard library can be obtained in a BasicObject subclass by referencing the desired constant from the root like ::File or ::Enumerator. ...在Ruby标准库中访问类和模块可以在BasicObject子类中获得,方法是从根目录中引用所需的常量,例如:: File或:: Enumerator。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM