如果我有一个名为app.rb
这需要另一个名为foo.rb
,Ruby 在幕后做了什么来使定义的常量foo.rb
变得可用在app.rb
?
来自 Yukihiro Matsumoto 的《Ruby 编程语言》:
使用 load 或 require 加载的文件在不同的新顶级作用域中执行
从调用 load 或 require 的那一个。加载的文件可以看到全局所有
加载时已经定义的变量和常量,但它没有
可以访问启动加载的本地范围。
我很难想象这一点。
例如:
foo.rb:
class Foo
def hello
puts "Hello, world!"
end
end
app.rb:
require_relative "foo"
foo_obj = Foo.new
foo_obj.hello # => "Hello, world!"
p Object.constants.grep /^Foo/ # => [:Foo]
Ruby 做了什么来添加Foo
常数进入Object
class?
嗯,非常直接,它查找作为参数给出的路径require
在当前 $LOAD_PATH 中的所有目录中。如果它在 $LOAD_PATH 的基本路径之一中找到具有该部分路径的文件,则会加载该文件。它还将其标记为已加载 - require 永远不会加载同一个文件两次,如果你第二次需要同一个文件两次基本上是无操作。
关于本地范围,非常简单:
foo = "x"
require 'some_file'
那里需要的 some_file (无论是否加载require
or load
)无权访问该局部变量“foo”。这是not就像代码是在加载/需要时粘贴的一样。相反,它被加载到它自己的本地范围中,不与加载/需要它的上下文共享任何本地变量。
同样,局部变量设置在所需的内部some_file
在 require 之后,在其外部也不可见。再说一遍,它是not就像此时代码已被粘贴一样。代码已加载,但在加载/需要时它不与上下文共享任何局部变量访问权限。
您可能预料到,也可能没有想到。就是这样,就是这个意思。
但这仅适用于局部变量。在所需的 some_file 之外定义的常量仍然可用;并且在所需的 some_file 中定义的常量在加载后仍然可用于其他事物。回想一下,Ruby 类实际上是通过常量访问的(SomeClass 是一个常量,它指向实际的类)。因此,这就是为什么 some_file 中定义的常量在被要求或加载后可用于任何其他代码。
除了查看 C 实现(这也超出了我的范围)之外,我不确定如何回答“它做了什么才能使之成为可能”。它只是...将文件加载到当前的 ruby 环境中。这就是让它成为可能的原因。但它加载它就好像它在它自己的局部变量范围内一样,这就是它不共享局部变量的原因。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)