在proc中设置全局

时间:2010-02-17 05:07:06

标签: ruby

我一直在努力更好地理解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.为什么两个例子之间存在差异?

3 个答案:

答案 0 :(得分:11)

它非常简单,实际上:$SAFE的行为与您对全局变量的预期不同是因为它不是全局变量。这是一个神奇的独角兽thingamajiggy。

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

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

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

答案 1 :(得分:3)

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

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

请参阅http://ruby-doc.org/docs/ProgrammingRuby/html/taint.html

原则上不应该使用赋值降低$ SAFE的值,但是它附加到执行上下文,例如,多线程程序可以在不同的线程中有多个$ SAFE值。 ..

答案 2 :(得分:1)

$DOOR的值必须为2。因为$DOOR全局变量已重新初始化为1到2。关于Global Variables的更多细节。

通过设置$SAFE变量,

$SAFE安全级别。默认情况下是 设为零。

proc中的

$SAFE将在内存中存在,直到范围结束。然后它显示先前设置的值,即1.检查此here以及{{3}的更多内容}

相关问题