Ruby类,包含和作用域 [英] Ruby classes, include, and scope
问题描述
包括模块如何影响范围?具体来说,在此示例中:
How does including a module affect scope? Specifically, in this example:
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
测试1 可以正常工作,但是测试2 和测试3 在没有注释掉的import ModuleB
的情况下会失败.
test 1 works fine, but test 2 and test 3 fail without the commented-out import ModuleB
.
- 为什么
ClassA
在范围内的ModuleB
(测试1)内,但不在ClassB
内? - 为什么
import ModuleB
将ClassA
带入ClassB
中的范围?
- Why is
ClassA
in scope inside ofModuleB
(test 1) but not inClassB
? - Why does the
import ModuleB
bringClassA
into scope inClassB
?
推荐答案
关键字 class , module 和 def 范围门".他们创建了新的范围.
The keywords class, module and def are what is known as "scope gates". They create new scopes.
#!/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
在阅读书之后,我开始了解Ruby中的作用域元编程Ruby" .确实很启发人.
I began to understand scopes in Ruby after reading the book "Metaprogramming Ruby". It is truly enlightening.
编辑:针对下面的评论.
类本质上是Ruby常量(请注意,它是一个具有大写名称的对象).常量在范围内具有定义的查找算法. Ruby编程语言 O'Reilly的书很好地解释了这一点在第7.9节中.此博客文章.
A class is essentially a Ruby constant (notice that it is an object with a capitalized name). Constants have a defined lookup algorithm within scopes. The Ruby Programming Language O'Reilly book explains it well in section 7.9. It is also briefly described in this blog post.
在任何类或模块之外定义的顶级常量类似于顶级方法:它们在Object中隐式定义.当从类中引用顶级常量时,将在搜索继承层次结构时对其进行解析.如果在模块定义中引用了常量,则在搜索模块的祖先后将对Object进行显式检查.
Top-level constants, defined outside of any class or module, are like top-level methods: they are implicitly defined in Object. When a top-level constant is referenced from within a class it is resolved during the search of the inheritance hierarchy. If the constant is referenced within a module definition it does an explicit check of Object after searching the ancestors of the module.
这就是为什么在顶层包含ModuleB会使ModuleB中的类在所有模块,类和方法中可见的原因.
That's why include ModuleB at the top level makes the class in ModuleB visible in all modules, classes and methods.
这篇关于Ruby类,包含和作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!