【发布时间】:2013-01-08 04:56:32
【问题描述】:
我正在模块内编写一些类:
module A
end
module A::B
def foo
print "foo"
end
end
class A::B::C
end
A::B::C.new.foo # => NoMethodError: undefined method `foo' for #<A::B::C...>
如何在模块 B 中定义方法以在类 C 中调用?
【问题讨论】:
我正在模块内编写一些类:
module A
end
module A::B
def foo
print "foo"
end
end
class A::B::C
end
A::B::C.new.foo # => NoMethodError: undefined method `foo' for #<A::B::C...>
如何在模块 B 中定义方法以在类 C 中调用?
【问题讨论】:
Ruby 中的命名空间并不像您想象的那样工作。
没有“命名空间方法”这样的东西。 A::B#foo 是 模块 A::B 上的一个实例方法——它是A 命名空间中名为B 的模块。
命名空间模块/类之间有没有特殊的继承关系。它们本质上纯粹是组织性的,除非定义很长(例如module A; module B; end; end),因为它们会影响词法范围。
如果你想在A::B::C 中获得A::B 的方法,你必须在A::B::C 中获得include A::B,就像在其他任何地方一样。您必须这样做,因为如上所述,命名空间模块/类没有什么特别之处,它与任何其他模块/类的处理方式相同。
【讨论】:
就好像你在写:
module A::B
def foo
print "foo"
end
class C
end
print 'C.instance_methods : '; p C.instance_methods(false)
#=> C.instance_methods : []
end
C 不会自动继承 foo。继承实例方法只有两种方式:
class C < super_class 其中super_class 是返回类的表达式
包括一个模块:
class C
include <some module>
有关超类链的说明,请参阅How does Inheritance work in Ruby? 和Ruby: Module, Mixins and Blocks confusing?
【讨论】:
class A::B::C
include A::B
end
【讨论】:
include吗?