在proc中设置全局

Fra*_*ois 6 ruby

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

$SAFE = 1
puts $SAFE # 1  
proc {
  $SAFE = 2
  puts $SAFE  # 2
}.call
puts $SAFE # 1   
Run Code Online (Sandbox Code Playgroud)

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

如果不是使用单词$SAFE我将其更改为不同的单词,例如$DOOR:

$DOOR = 1
puts $DOOR 
proc {
  $DOOR = 2
  puts $DOOR  
}.call
puts $DOOR  
Run Code Online (Sandbox Code Playgroud)

那么$DOORproc 之后的值是2而不是1.为什么两个例子之间存在差异?

Jör*_*tag 11

这很简单,真的是:之所以$SAFE不像你期望的全局变量,是因为它不是一个全局变量.这是一个神奇的独角兽thingamajiggy.

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

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

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