【问题标题】:Why does `include` behave differently at the top level?为什么`include`在顶层表现不同?
【发布时间】:2016-01-01 10:38:04
【问题描述】:

当我执行include Foo 时,我使用了以下钩子来检查正在执行包含的模块:

module Foo
  def self.included(includer)
    puts includer
  end
end

Module#include 在模块(通常使用它的地方)与在顶层的行为不同。在模块内部,self 是模块,它是Module 的一个实例。当我调用include 时,执行包含的模块是self 是什么

module Bar
  puts self   # => Bar
  include Foo # => includer: Bar
end

在 ruby​​ 脚本的顶层,selfmain,它是 Object 的一个实例。当我在顶层调用include 时,包含的模块是Objectself 的类是

puts self    # => main
include Foo  # => includer: Object

谁能解释一下原因?

顶层对象必须是特殊的;如果我在上面调用to_sinspect,它只会显示main,但如果我使用Object.new 创建另一个对象并调用to_sinspect,我会得到通常的对象符号:@ 987654344@.

【问题讨论】:

  • 通过Module#included的文档,它接收到调用Module#include的模块或对象。
  • "main" 是 Ruby 程序的特殊顶级 Object 实例和初始执行上下文。它在内部定义的方法成为其(私有)实例方法方面也很特殊。
  • 对象没有include 方法,只有模块有。 mainObject 的一个实例,而Module 不在祖先中。它必须include 的特殊单例方法版本,仅适用于 main,对吧?
  • 特别的是main,而不是include
  • 红宝石“顶级”有点奇怪和独特,它有时表现得像 Object 的实例,有时又像 Object 类。 banisterfiend.wordpress.com/2010/11/23/…

标签: ruby class include main


【解决方案1】:

main 是特殊的,有自己的include 定义。也就是说,它的singleton_class 有自己的include 定义。为了证明这一点:

irb(main):017:0> method(:include).owner
=> #<Class:#<Object:0x007fc0398c6468>>
irb(main):018:0> self.singleton_class
=> #<Class:#<Object:0x007fc0398c6468>>

您想到的include 是在Module 上定义的:

MyClass.method(:include).owner
=> Module

所以,include 在“顶层”的行为不同,也就是我们调用main 的对象,原因很简单:它只是与Module#include 完全不同的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 2015-11-01
    相关资源
    最近更新 更多