我不认为我完全理解Ruby的$ SAFE变量的范围。我原以为它是全球性的,一旦增加,就无法减少。但是,我的实验表明我错了。考虑这两个文件中的代码:
--- dev.rb ---
#!/usr/bin/ruby -w
require_relative './mymod.rb'
puts '$SAFE in script: ' + $SAFE.to_s
--- mymod.rb ---
puts '$SAFE before: ' + $SAFE.to_s
$SAFE = 1
puts '$SAFE after: ' + $SAFE.to_s
这是输出:
$SAFE before: 0
$SAFE after: 1
$SAFE in script: 0
所以我觉得$ SAFE再次减少了。我担心我发现这非常违反直觉。有人可以解释这种行为吗?
答案 0 :(得分:2)
$SAFE
实际上是线程和proc local。一个简单的例子来观察这个:
->{ $SAFE=1; p $SAFE }.() # => 1
p $SAFE # => 0
然而in the current development version it's a process global variable就像你预期的那样a backward incompatible change,所以它可能会在下一个版本(2.6)之前被还原或修改(只有本地线程)。
这不是整个故事,但是随着这个改变,你的例子的输出仍然是0 1 0.所以发生了什么?那么,在您的情况下,require_relative
(和require
)的明显无证行为是安全级别更改背后的原因。与load
不同,它只关心文件名(受污染?)和目录(世界可写?)的当前安全级别,但是在内容加载$SAFE
is temporarily set to 0之前。虽然官方文档中似乎没有提到这一点,但 David Flanagan 和 Yukihiro Matsumoto (!)。{/ p>。