为什么以下示例中存在错误?
class ClassA
class ClassB
end
class ClassC
def test
ClassB.new
end
end
end
p ClassA::ClassC.new.test # => #<ClassA::ClassB:0x0000010103f860>
class ClassA
class ClassD
def test
ClassB.new
end
end
end
p ClassA::ClassD.new.test # => #<ClassA::ClassB:0x0000010103f010>
class ClassA::ClassE
def test
ClassB.new
end
end
p ClassA::ClassE.new.test # => NameError: uninitialized constant ClassA::ClassE::ClassB
是否有其他方法可以创建ClassE
,而不是键入class ClassA; class ClassE
?
答案 0 :(得分:1)
嗯,是的,如果您定义测试方法以返回ClassA::ClassB.new
: - )
您也可以使用const_missing
进行游戏,以便调用ClassA.const_get
。
否则ClassB
不在当前范围内,此时此范围仅为ClassA::ClassE
和Object
。当您首次打开ClassA
,然后ClassE
时,ClassB
的查找首先在ClassA::ClassE
中完成,然后在ClassA
中找到Object
也请查看{{1}}。
答案 1 :(得分:0)
Marc-André Lafortune建议的自定义Object#const_missing
方法将是
def Object.const_missing(name)
@looked_for ||= {}
key = self.to_s + '~' + name.to_s
raise "Class not found: #{name}" if @looked_for[key] == key
return @looked_for[key] if @looked_for[key]
@looked_for[key] = key
if self.to_s.include? '::'
klass = Object
self.to_s.split('::')[0..-2].each do |klass_string|
klass = klass.const_get klass_string
end
return @looked_for[key] = klass.const_get(name) if klass # klass.is_a?(Class)
end
raise "Class not found: #{name}"
end
一些相关问题: