为什么Ruby模块内核存在?

时间:2016-07-10 07:23:56

标签: ruby oop

OO Design in Ruby 一书中,Sandi Metz说模块的主要用途是用它们实现鸭子类型,并将它们包含在所需的每个类中。为什么Ruby Kernel包含在Object中?据我所知,它不会在其他地方使用。使用模块有什么意义?

2 个答案:

答案 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中的私有实例方法。