Ruby 类、包含和作用域

标签 ruby module scope

包含模块如何影响范围?具体来说,在这个例子中:

module ModuleA
  class ClassA
    def initialize
      puts "test passed"
    end
  end
end

module ModuleB
  include ModuleA

  # test 1
  C = ClassA.new

  class ClassB
    def initialize
      c = ClassA.new
    end
  end
end

# test 2 and 3 fail without this
#include ModuleB

module ModuleC
  # this doesn't help
  include ModuleB

  # test 2
  ClassB.new

  # test 3
  ModuleB::ClassB.new
end

test 1 工作正常,但 test 2test 3 在没有注释掉 import ModuleB 的情况下失败.

  • 为什么 ClassAModuleB 的范围内(测试 1)但不在 ClassB 内?
  • 为什么 import ModuleBClassA 引入 ClassB 的作用域?

最佳答案

关键字classmoduledef 就是所谓的“作用域门”。他们创建新的范围。

#!/usr/bin/env ruby

module ModuleA
  class ClassA
    def initialize
      puts "test passed"
    end
  end
end

module ModuleB
  include ModuleA

  # test 1
  c = ClassA.new  # this works as ModuleA has been included into this module

  class ClassB  # class is a scope gate, creates new scope
    def initialize  # def is a scope gate, creates new scope
      c = ModuleA::ClassA.new  # must fully qualify ClassA
    end
  end

  ClassB2 = Class.new do  # no scope gate
    define_method :initialize do # no scope gate
      c = ClassA.new  # this works, no need to fully qualify
    end
  end
end

b = ModuleB::ClassB.new
b2 = ModuleB::ClassB2.new

在阅读 book "Metaprogramming Ruby" 后,我开始了解 Ruby 中的作用域.这确实很有启发性。

编辑:回应下面的评论。

类本质上是一个 Ruby 常量(注意它是一个名称大写的对象)。常量在范围内有定义的查找算法。 The Ruby Programming Language O'Reilly 的书在第 7.9 节对此进行了很好的解释。在此 blog post 中也对其进行了简要描述。 .

在任何类或模块之外定义的顶级常量就像顶级方法:它们在 Object 中隐式定义。当从类中引用顶级常量时,它会在搜索继承层次结构时被解析。如果常量在模块定义中被引用,它会在搜索模块的祖先后对 Object 进行显式检查。

这就是为什么在顶层包含 ModuleB 会使 ModuleB 中的类在所有模块、类和方法中可见。

关于Ruby 类、包含和作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7549625/

相关文章:

ruby - 在 Xcode 机器人触发器中安装 Pod

ruby - 无法从 CSV 中删除空行

ruby-on-rails - 有没有办法通过命令行向 Rails 添加路由?

html - Rails 从 Helper 模块返回多个 content_tags

javascript - 在 node.js 上扩展 lodash/下划线?

java - 增强型 for 循环中局部变量的范围

java - 如何通过 Weld 获得Java SE中的ApplicationScoped生产者?

ruby-on-rails - 仅使用 ruby​​ 的 Rails authlogic 密码哈希算法

angular - Angular 模块中的依赖关系方向

c++ - 没有内部作用域的 if 语句?