Sam*_*mes 0 ruby global global-variables
我已经阅读了关于全局变量的C2Wiki,我有三个关于它们的问题(在这篇文章的底部).主要问题是:如果全局变量如此糟糕,为什么Ruby会有它们?
此外,我注意到一些关于Ruby中全局变量的有趣行为,这使得它们与常规全局级常量的工作方式不同.
1.引用未定义的全局变量返回nil.引用未定义的全局常量返回NameError:
2.2.3 :001 > $THING
=> nil
2.2.3 :002 > THING
NameError: uninitialized constant THING
from (irb):2
from /Users/makerslaptop82/.rvm/rubies/ruby-2.2.3/bin/irb:15:in `<main>'
Run Code Online (Sandbox Code Playgroud)
2. irb用两者初始化$stdout并STDOUT定义.您可以重新定义$stdout,这不会影响STDOUT:
2.2.3 :001 > $stdout
=> #<IO:<STDOUT>>
2.2.3 :002 > STDOUT
=> #<IO:<STDOUT>>
2.2.3 :003 > $stdout = IO.new(6)
=> #<IO:fd 6>
2.2.3 :004 > $stdout
=> #<IO:fd 6>
2.2.3 :005 > STDOUT
=> #<IO:<STDOUT>>
Run Code Online (Sandbox Code Playgroud)
我的问题是:
nil而不是NameError?这个选择是故意的吗?为什么?全局变量也不错.他们不是邪恶的.它们令人难以置信,非常强大.这就是你不应该使用它们的原因.
全局变量是全局变量 - 可以在代码中的任何位置访问和修改它们.单个全局变量有可能影响所有类,所有函数,每个库的所有类和函数或加载到项目中的依赖项,以及加载的每个项目的所有类和函数您的项目作为依赖项,以及加载这些项目的项目,等等,永远和永远,其余时间.
第二个人开始使用全局变量感觉很舒服,命名空间变得非常混乱,我们左右冲突,编程语言本身的稳定性受到威胁.这就是为什么强调和反复劝阻使用全局变量的原因.
但全球变量并不坏.它们就像标有"仅用于紧急车辆"的高速公路车道,或者像玻璃后面的那些斧头标记为"紧急情况下的破碎玻璃".
完全有可能在某个时候,在遥远的未来,你会有一个非常不寻常的情况,值得使用一个全局变量.但那一天不是今天.它可能不是明天,也可能是一个月后,也可能是一年之后.日常生活,每日代码 - 它并没有要求全球变量的肆无忌惮的力量.
$stdout是全局变量有时重要的一个很好的例子.$stdout是ruby中的默认流 - 如果没有指定其他流,则会打印事物.$stdout应该可以从每个类和每个库中的每个功能访问,因为它像一个巨大的漏斗,将所有输出铲到一个位置.全世界都知道并同意$stdout红宝石中存在,并且其用途已被充分记录,因此其功能得到了很好的管理.
这不应该与STDOUT表示实际管道的常量相混淆,该常量管道在ruby与其父程序(通常是终端)之间建立流.$stdout = STDOUT默认情况下,但$stdout可以更改为任何内容.如果希望程序打印到文件,则可以更改$stdout为文件流.
我不认为这个名字的选择让一个经验丰富的红宝石混淆.设计一个变量进行修改,并将常量设计为常量.$ stdout和STDOUT之间的区别在于可以修改前者以更改程序的标准输出位置,后者是常量,始终指向stdout流.资本化创造了一个与众不同的世界,并传达了截然不同的含义.
至于为什么全局常量未初始化和全局变量nil,这实际上与全局变量无关.Ruby会自动将所有变量初始化为nil.您可以使用实例变量(例如@foo或)轻松查看此内容@@foo.在几乎所有情况下,未定义的局部变量都会抛出一个NameError因为ruby无法判断它是变量还是方法.但在奇怪的情况下,它们也被初始化为nil:
puts foo # => NameError: undefined local variable or method 'foo'
foo = 42 if false
puts foo # => nil
puts bar # => NameError
bar = bar
puts bar # => nil
Run Code Online (Sandbox Code Playgroud)
Ruby中有意识的设计选择是不自动初始化常量.因为根据定义,常量是初始化一次然后从未改变的东西,它会使常量的定义首先打破nil,然后在代码中稍后使用不同的值.
我还应该提到全局常量被认为是可以接受的,即使是那些将全局变量称为坏的人也是如此.区别在于常量只能分配一次,如果再次分配,通常会发出警告或错误.这可以保护程序员免受冲突的全局常量可能导致问题的情况的影响.