在proc中设置全局

我一直在努力更好地理解Ruby,这里有一些我遇到的问题:

$SAFE = 1 puts $SAFE # 1 proc { $SAFE = 2 puts $SAFE # 2 }.call puts $SAFE # 1 

以上代码部分取自eRB的源代码重写,以更好地突出显示示例。 基本上在proc中,可以将$SAFE的值设置为任何想要的值,并且在proc之后, SAFE的值返回到proc之前的值。

如果不是使用单词$SAFE而是将其更改为其他单词,例如$DOOR

 $DOOR = 1 puts $DOOR proc { $DOOR = 2 puts $DOOR }.call puts $DOOR 

然后在proc之后$DOOR的值是2而不是1.为什么两个例子之间有区别?

它真的很简单: $SAFE行为与你对全局变量的预期不同是因为它不是一个全局变量。 这是一个神奇的独角兽thingamajiggy。

Ruby中有很多神奇的独角兽故事,遗憾的是它们没有很好的文档记录(事实上并没有完全记录),因为替代Ruby实现的开发人员发现了困难的方法。 这些东西都表现得不同,而且(看似)不一致,而且它们共同的唯一两件事就是它们看起来像全局变量,但不像它们那样。

有些人有本地范围。 有些具有线程局部范围。 有些神奇地改变,没有人分配给他们。 有些人对翻译有神奇的意义,并改变语言的行为方式。 有些人还附加了其他奇怪的语义。

$SAFE几乎具有上述所有function:它是线程本地的,这意味着如果在一个线程中更改它,它不会影响其他线程。 它是本地的,这意味着如果您在本地范围(如类,模块,方法或块)中更改它,它不会影响外部范围(如您所发现的)。 它对于解释器具有神奇的意义,因为将其设置为不同于0的值会使某些事情无效。 它还有其他奇怪的语义,你只能增加它的价值,永远不会减少它。

我不知道为什么$ SAFE正在以这种方式工作,但我知道它是一个预定义的全局变量,具有与受污染的外部数据和线程相关的神奇含义。

所以不要将它用作程序对象。

见http://ruby-doc.org/docs/ProgrammingRuby/html/taint.html

顺便说一句,应该可以通过赋值降低$ SAFE的值,但它附加到执行上下文,例如,multithreading程序可以在不同的线程中有多个$ SAFE值…

$DOOR的价值必须是2。 因为$DOOR全局变量已重新初始化为1到2。 有关全局变量的更多详细信息。

通过设置$SAFE变量$SAFE安全级别。 默认情况下,它设置为零。

proc中的$SAFE将在内存中存在,直到范围结束。因此,它显示先前设置的值,即1.在此处查看更多内容以及文档