Ruby require如何始终加载到顶级范围?
考虑以下Ruby代码:Ruby require如何始终加载到顶级范围?,ruby,Ruby,考虑以下Ruby代码: class A require 'json' end 因为Ruby是逐行解释和执行代码的,所以我希望JSON的作用域是在 然而: irb(main):005:0> A::JSON Traceback (most recent call last): 4: from /usr/bin/irb:23:in `<main>' 3: from /usr/bin/irb:23:in `load' 2: from
class A
require 'json'
end
因为Ruby是逐行解释和执行代码的,所以我希望JSON的作用域是在
然而:
irb(main):005:0> A::JSON
Traceback (most recent call last):
4: from /usr/bin/irb:23:in `<main>'
3: from /usr/bin/irb:23:in `load'
2: from /usr/lib/ruby/gems/2.7.0/gems/irb-1.2.1/exe/irb:11:in `<top (required)>'
1: from (irb):5
NameError (uninitialized constant A::JSON)
irb(main):004:0> JSON
=> JSON
irb(main):005:0>A::JSON
回溯(最近一次呼叫最后一次):
4:from/usr/bin/irb:23:in`'
3:from/usr/bin/irb:23:in'load'
2:from/usr/lib/ruby/gems/2.7.0/gems/irb-1.2.1/exe/irb:11:in`'
1:来自(irb):5
NameError(未初始化的常量A::JSON)
irb(主):004:0>JSON
=>JSON
require
如何始终将gems加载到顶级范围?实现了require
,因此它可以访问普通Ruby代码无法访问的内部功能。例如,它可以手动退出其当前作用域,并在顶层执行代码。这就是“如何”
至于“为什么”?想象一下,如果您可以将require
放入一个特定的范围,这将极易被破坏,因为它会将顶级self
从main
(这是一个对象
)更改为。。。任何内容(在您的示例中,它将是A
,它是类
)。当您的代码是require
d时,通常很难预测会发生什么
通过始终在顶层执行加载的代码,结果总是一致的。您可以使用内置的钩子机制(包括、扩展、前置、继承)从加载您的作用域访问特定的
self
s。在Rubinius中,Kernel#require
是在纯Ruby(不是在C中)和核心库(不是在VM中)中实现的,但其行为完全相同。因此,许多Ruby实现中的一个碰巧在VM中用C实现它,这一事实并不能解释为什么require
在所有Ruby实现中的行为方式。不管它在其他Ruby中如何实现,这就是它在标准Ruby中的实现方式。除了对所有已知的实现进行调查之外,我不知道还能如何回答