为什么 Ruby 模块包含排除模块的单例类?
当在 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)后,我发现存在一个实现困难(不是不可克服的,但都是一样的),但这是唯一的原因吗?这个限制还有其他原因吗?
谢谢
When classes are inherited in Ruby the singleton classes are also inherited:
class A
def self.hello
puts "hello"
end
end
class B < A
end
B.hello #=> "hello"
Yet with modules, this is not the case:
module M
def self.goodbye
puts "goodbye"
end
end
class A
include M
end
A.goodbye #=> NameError
To get around this limitation many ppl resort to this ugly hack:
module M
def self.included(c)
c.extend ClassMethods
end
module ClassMethods
def goodbye
puts "goodbye"
end
end
end
Ok, so my question: is there a theoretical/conceptual reason behind this limitation on modules? or was it just an implementation difficulty?
After looking at the C source code (YARV/MRI) I can identify there is an implementation difficulty (not insurmountable, but one all the same), but is this the sole reason? Are there any other reasons for this limitation?
thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
除非有人能提出令人信服的论据,否则我认为限制只是在于实施难度。尽管如此,我最近几天一直在解决这个问题,并且(在测试版中)有一个名为
include_complete
的新版本的 include,它解决了这些困难,并允许模块继承像类继承一样工作(带来在单例中)在此处查看该项目: http://github.com/banister/include_complete
并注意该项目仍处于测试阶段,但到目前为止似乎仍然按预期工作
Unless anyone can come up with a compelling argument, i feel that the limitation is just down to implementation difficulty. Nonetheless i've been working on the problem the last couple of days and have (in beta) a new version of include called
include_complete
that gets around these difficulties and allows modules inheritance to work like class inheritance (bringing in the singleton)Check out the project here: http://github.com/banister/include_complete
And beware the project is still very much in beta, but still seems to work as desired so far
警告:以下只是猜测。
如果您使用类,则需要单例类方法,因为您依赖它们来创建对象(例如
MyClass.new
)。如果您使用模块,则不需要它们,因为您不能纯粹从模块创建对象。Warning: the following is just speculation.
If you're using a class, you'll need singleton class methods, because you rely on them to create the object (eg
MyClass.new
). If you're using a module, you don't need them, because you can't create objects purely from a module.