【问题标题】:What is the purpose of `Kernel`?“内核”的目的是什么?
【发布时间】:2014-05-20 12:46:36
【问题描述】:
  1. Kernel 模块的用途是什么?如果当前在Kernel 上定义的所有东西都在Object 上定义,并且没有Kernel 这样的模块,会发生什么变化?
  2. 当我想定义一个可以在任何对象上调用的方法时,我应该在Kernel 还是Object 上定义它?

【问题讨论】:

  • 泽,非常尊重你。我认为这是一个很好的问题,我很高兴看到答案。
  • @naomik 谢谢。我看到你偶尔会出现在 Ruby 问题上。
  • 这里有一些有趣的花絮可能相关(对于 v.2.1.0):Kernel.private_methods-Object.private_methods => [:append_features, :extend_object, :prepend_features, :refine, :module_function](为什么不将这些混入 Object?)和 Kernel.singleton_methods.size => 61

标签: ruby oop


【解决方案1】:

我将从一个问题开始:self 在典型的Kernel 方法(例如puts)中是什么?在puts 中最接近有意义的self 的可能是Ruby 运行时本身。同样对于其他“真正想要成为函数的方法”,如Arrayfork。因此,您可以将 Kernel 视为方法的垃圾场,这些方法或多或少是对 Ruby 本身的命令或消息。

Kernel 也有一些奇怪的方法,比如 subchop,它们只对一次性的 ruby -e 脚本有用。这些东西倾向于使用$_ 作为隐含的self,但我认为它们可以被视为上述“Ruby 运行时命令”的特例。

当您希望能够在任何对象上调用该方法时,该方法会去哪里?我会说它会进入Object。如果该方法真的是一个变相的函数并且没有有意义的self,那么它会进入Kernel

【讨论】:

  • “垃圾场”!你当然有办法用词,μ。 def Kernel.lets_see; puts "self = #{self}"; end; Kernel.lets_see => Kernel 有什么启示吗?
  • 还有一些东西(比如Delegator)是从BasicObject而不是Object派生的,但随后包括Kernel。如果一切都绑定在 Object 中,事情就不会那么简单了。
  • @AndrewMarshall AFAIK BasicObject 最近(对于“最近”的一些定义)从 Object 中分离出来,原因是您所说的,内核一直存在。
  • @sawa 是的,但那是因为self 必须是一些东西。我想说selfputs 这样的方法中没有多大意义;我可以说'pancakes'.send(:puts, 11) 但这不会改变puts 的行为,因为puts 是一个函数,它只是内核中的一种方法,这是必要的。我承认我觉得这里的术语有点麻烦,但我想你知道我在说什么。
  • 对 mu 的进一步回答:任何时候您在 Kernel 上定义新方法时,它都应该是 private(因此它永远不会被显式接收器调用)。
猜你喜欢
  • 2015-06-11
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 2013-08-13
  • 1970-01-01
相关资源
最近更新 更多