在 OO Design in Ruby 一书中,Sandi Metz说模块的主要用途是用它们实现鸭子类型,并将它们包含在所需的每个类中。为什么Ruby Kernel
包含在Object
中?据我所知,它不会在其他地方使用。使用模块有什么意义?
答案 0 :(得分:3)
正如您已经指出的那样:模块提供了一种收集和构造行为的方法,内核模块也是如此。这个模块早期混合到Object类中,因此每个Ruby类都将提供这些方法。在层次结构之前只有一个BasicObject,它的子对象目的只是通过内核方法扩展。 BasicObject只有7种非常 basic 的方法,如new
,__send__
或__id__
。
class Object < BasicObject
include Kernel # all those many default methods we appreciate :)
end
答案 1 :(得分:3)
理想地,
Object
类上定义,而Kernel
模块中。 Kernel#puts
,例如,它的接收器没有做任何事情;它不会在其上调用私有方法,它不会访问它的任何实例变量,它只会对其参数起作用。
Ruby中的程序是伪造的,使用Ruby的功能可以省略等于self
的接收器。它们通常也是私有的,以防止它们被明确的接收器调用,因此更加令人困惑。例如,"Hello".puts
会打印一个换行符,因为puts
只关心它的参数,而不是它的接收者。通过将其设为私有,它只能被称为puts "Hello"
。
实际上,由于Ruby的悠久历史,这种分离并不是一直严格遵循的。另外复杂的是,Kernel
中记录了一些Object
方法,反之亦然,甚至还有这样一个事实:当你定义看起来像的东西时全局程序,并且通过上述推理最终应该在Kernel
中,它实际上最终成为Object
中的私有实例方法。