我认为在类<<<自我阻挡和自我宣告的人.前缀,但有:
module A VAR = 'some_constant' end class B extend A class << self def m1 puts VAR end end def self.m2 puts VAR end end B.m1 # => OK B.m2 # => uninitialized constant B::VAR
为什么A的常数可用于m1而不是m2?
解决方法
在Ruby中,常量查找与方法查找不同.对于方法查找,调用foo始终与调用self.foo相同(假设它不是私有的).调用常数FOO与self :: FOO或singleton_class :: FOO非常不同.
使用不合格的常数(例如FOO)将在当前打开的模块中进行查找.使用模块Mod,类Klass,类<< obj或module_eval和变体.当定义m1时,它们是B,然后是B.singleton_class.当定义m2时,只有B被打开.
module Foo X = 42 class Bar def self.hello X end end end
在这段代码中,Foo :: Bar.hello将返回42,即使X不是Bar,它的单例类或祖先的常量.此外,如果您以后将一个常量X添加到Bar,那么该值将被返回.最后,以下定义不等同:
module Foo X = 42 end class Foo::Bar def self.hello X end end Foo::Bar.hello # => uninitialized constant Foo::Bar::X
实际上,当定义了hello时,只有类Foo :: Bar被打开,而在前面的例子中,Foo和Foo :: Bar都打开了.
最后一个例子,显示一个明确的范围可以带有继承的差异:
class Base X = 42 def self.foo X end def self.bar self::X end end class Parent < Base X = :other end Parent.foo # => 42 Parent.bar # => :other
在你的情况下,你可能想要包括你的模块,而不是扩展它,否?
否则,您可以使用singleton_class :: VAR,您的代码将按照您的期望工作.
module A VAR = 'some_constant' end class B extend A class << self def m1 puts singleton_class::VAR # not necessary here,as singleton_class is opened end end def self.m2 puts singleton_class::VAR # necessary here! end end B.m1 # => OK B.m2 # => OK