Ruby $SAFE变量的范围
我认为我不太了解Ruby的$SAFE变量的范围。我原以为它是全球性的,一旦增加,就不能减少。然而,我的实验表明我错了。考虑这两个文件中的代码:Ruby $SAFE变量的范围,ruby,security,Ruby,Security,我认为我不太了解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 a
--- 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
实际上既是线程又是安全的。观察这一点的一个简单示例:
->{ $SAFE=1; p $SAFE }.() # => 1
p $SAFE # => 0
然而,正如您所期望的那样,它可能会在下一个版本(2.6)之前恢复或修改(仅线程本地)
这还不是全部内容,尽管与此更改一样,示例的输出仍然是0 1 0。发生了什么事?在您的案例中,
require\u relative
(和require
)的明显未记录行为是安全级别更改背后的原因。与load
不同,它只关心文件名(污染?)和目录(世界可写?)的当前安全级别,但在加载内容之前。虽然官方文件中似乎没有提到这一点,但这是大卫·弗拉纳根(David Flanagan)和松本幸弘(Yukhiro Matsumoto)(!)的作品。我的印象是,它从未发挥应有的作用,给人一种虚假的安全感。这不是一个普通的全局设置,而是一种通过.tainted?
切换污点跟踪的方法,$SAFE
中的任何更改都可能在文件级别进行。我已经阅读了您链接到的线程。幸运的是,Ruby中仍然存在污染,应该保持这种状态。但是,如果不卷入这场圣战,问题仍然是,美元安全的范围是什么?它看起来也不完全是文件级的。污染与$SAFE
的行为是分开的,我认为您需要在这里进行更多的探索。好的,我仍在学习stackoverflow的评论系统,并不打算保存以前的评论。我的意思是:我已经读了你链接到的那个帖子。幸运的是,Ruby中仍然存在污染,应该保持这种状态。但是,如果不卷入这场圣战,问题仍然是,美元安全的范围是什么?它似乎也不完全是文件级的。如果您需要一个文件,请在该文件中设置$SAFE,然后调用该文件中的一个方法,$SAFE返回到该方法中以前的值。我不完全确定,但我认为如果您运行一些实验,您可以找到答案,并可能用您的结果组成一个自我回答。不幸的是,“安全”和“线程安全Ruby”有很多搜索词,这使得信息更难找到。哇!回答得好!好的,我会考虑所有这些。谢谢