【问题标题】:undef methods from Kernel class still able to call them from Kernel.singleton_class来自内核类的 undef 方法仍然能够从 Kernel.singleton_class 调用它们
【发布时间】:2014-07-24 22:18:42
【问题描述】:
module Kernel
  undef rand
  undef srand
end

为什么 Kernel.rand 还在工作?我知道该方法是在 Kernel.singleton_class 上调用的,但是单例类包括未定义方法的内核模块。这只是红宝石黑魔法的一个例子,还是我从红宝石对象模型中遗漏了一些东西?谢谢!

【问题讨论】:

    标签: ruby


    【解决方案1】:

    尽管像这样对现有的主模块进行猴子补丁是一种非常糟糕的做法,尤其是 Kernel,它是 Ruby 中每个 object 的祖先。它可能在您或其他项目中产生非常糟糕和严重的影响,它包括在内。虽然为了理解上面的代码发生了什么,您可以更改:

    module Kernel
      undef rand
      undef srand
    end
    

    module Kernel
      class << self
        undef rand
        undef srand
      end
    end
    # OR, much cleaner:
    Kernel.instance_eval { undef :rand, :srand }
    

    通过class &lt;&lt; self,您正在劫持内核的单例类/特征类,并在那里取消定义单例方法randsrand。 这些是内核的单例方法而不是实例方法。

    原来:

     Kernel.singleton_methods.grep(/rand/)
    => [:srand, :rand]
    

    之后:

     Kernel.singleton_methods.grep(/rand/)
    => []
    

    我知道该方法是在 Kernel.singleton_class 上调用的,但是单例 类包括内核模块,其方法未定义。

    类/模块中的

    include 不包括该类/模块中的 单例方法randsrand 仅在内核的 singleton_class 中有效定义,并且只能从那里取消定义。

    更新
    如前所述,顶级对象(main) 中的randsrand 仍然有效,但Kernel.randKernel.srand 将给出NoMethodError。原因:

    当一个模块包含在一个类或其他模块中时,Ruby 内部会创建一个特殊的 include 类,它保存当时定义的模块的引用,并添加类的祖先链中的那个类(虽然是隐藏的)。
    现在,Object 之前已经包含 Kernel。该实例的内核中存在的方法堆叠在隐藏的包含类中,并且可用于Object。这就是为什么main(Object 的实例)仍然持有这些方法的引用。
    这就是为什么rand 有效而Kernel.rand 无效的原因。

    【讨论】:

    • 这段代码的唯一目的是学习。 :) rand 和 srand 方法实际上是单例方法,而不是内核模块的实例方法。现在说得通了。但随后又出现了另一个问题。即使我有 undef 方法,为什么我仍然可以从顶层调用它们?谢谢你的回答!
    • 是的,这就是为什么我冒昧地解释它背后的工作理念。 :-) 对我来说,从顶层定义后不会调用它。请检查一次。
    • 我确实检查过了。在我在 Kernel mod 上取消定义它们之后,它们被称为“rand”和“srand”,它们仍然可以工作。这怎么可能?在红宝石 2.1 上测试。谢谢!
    • 我现在检查了它。你是对的,rand 在顶级(主)对象中仍然有效,但Kernel.rand 不再起作用。这是令人惊讶的。调查它...
    • @Viorel 想通了。增加了原因。还找到了一个很好的线程 - stackoverflow.com/a/9240443/1376448,它进一步解释了 include 模块的原因。 :)
    猜你喜欢
    • 1970-01-01
    • 2018-12-17
    • 2018-05-26
    • 2014-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 1970-01-01
    相关资源
    最近更新 更多