【发布时间】:2011-04-20 09:33:43
【问题描述】:
当类在 Ruby 中被继承时,单例类也被继承:
class A
def self.hello
puts "hello"
end
end
class B < A
end
B.hello #=> "hello"
但对于模块,情况并非如此:
module M
def self.goodbye
puts "goodbye"
end
end
class A
include M
end
A.goodbye #=> NameError
为了绕过这个限制,许多人使用了这个丑陋的黑客:
module M
def self.included(c)
c.extend ClassMethods
end
module ClassMethods
def goodbye
puts "goodbye"
end
end
end
好的,所以我的问题是:这种模块限制背后是否存在理论/概念上的原因?还是只是实施困难?
查看 C 源代码 (YARV/MRI) 后,我可以确定存在一个实现困难(不是无法克服,但都是一样的),但这是唯一的原因吗?这种限制还有其他原因吗?
谢谢
【问题讨论】:
-
他们为什么要这样做?包含模块与继承类不同。
-
@Mladen,我不买这个。如果概念上的区别如此清晰,那么为什么人们(甚至是非常顶级的 Ruby 程序员)试图通过使用
ClassMethodshack 来绕过这个限制?进一步——为什么模块的性质以某种方式暗示了这个特定的限制。 -
恕我直言,模块混合!= 多重继承,所以无论某些人可能在做什么并不能真正证明什么。顺便说一句,您能否通过一个真实的示例来说明对 hack 的需求,例如,通过包含模块
A并通过模块B扩展来实现相同的功能是无法实现的? -
@Mladen,你的例子正是黑客派上用场的地方......你不再需要到
include A和extend B,因为包括A就足够了.同样,简单地说“它们不同”而不给出任何解释也很弱。我的问题是这种差异背后的理论是什么......或者根本没有理论,这只是一个实施困难?查看源代码,我相信这只是一个实施困难。 -
请注意,我并不是说您的期望是错误的。简单地说,
include在文档中被明确定义为除了在模块上调用append_features之外什么都没有,这反过来意味着添加模块的常量、方法和模块变量。它不代表继承。
标签: ruby inheritance module singleton mixins