为什么ENV ['FOO'] = true会在Ruby中引发异常?

时间:2015-10-30 18:23:24

标签: ruby

ENV['FOO'] = true

提高no implicit conversion of true into String

puts ENV.class
Object < BasicObject

数组访问方法不是BasicObject的一部分。

不确定这是来自Rack,Rack Test还是其他宝石。

ruby​​ 2.2.3p173
机架(1.6.0)
rack-test(0.6.3)

2 个答案:

答案 0 :(得分:2)

了解ENV是什么非常重要:它是shell中定义的变量,位于脚本和Ruby之下,并且可供您运行的脚本使用或者你创建的任何子shell。

该环境只知道字符串,值表示为&#39; true&#39;或者&#39; false&#39;,而不是像Ruby truefalse这样的对象。

ENV['foo'] = true是尝试分配Ruby对象并失败。请改用ENV['foo'] = 'true'

以下是您如何使用它的一个小例子。我在一个名为&#34; test.rb&#34;:

的文件中有一行Ruby代码
puts ENV['foo']

如果我在shell中使用以下命令运行该代码:

foo=bar ruby test.rb

Ruby脚本输出ENV['foo']

的值
bar

这是因为foo=bar将系统环境变量foo初始化为&#39; bar&#39;在将控制权移交给Ruby之前。

我可以使用相同的变量来查看子shell中的值。将Ruby脚本更改为:

ENV['foo'] = 'baz'
puts `echo $foo`

并运行它设置环境变量“foo”&#39;到了&#39; bar&#39;在给予Ruby控制权之前,Ruby会将其更改为“baz”&#39;然后执行子shell以回显变量的输出,Ruby捕获因为我使用反引号:

foo=bar ruby test.rb

导致:

baz

正在打印。即使我最初将变量设置为&#39; bar&#39;,脚本也会将其设置为&#39; baz&#39;,只有子shell才能看到。

我认为可以提出一个很好的论据,即写入ENV应该自动使用to_s来避免这种情况,但它是任何编程语言中的许多问题之一。

答案 1 :(得分:2)

因为ENV class不仅仅是一个对象或一个哈希: ENV是一个类似哈希的环境变量访问器。

很明显它不是真正的heash,因为setter方法(ENV[name] = value)试图将值转换为字符串。

此外值得注意的是,它缺少普通哈希所具有的许多方法。