我早就意识到Ruby中的“常量”(即大写的变量名)不是真正的常量。与其他编程语言一样,对象的引用是存储在变量/常量中的唯一内容。 (补充工具栏:Ruby确实具有“冻结”被修改引用对象的功能,据我所知,这不是许多其他语言提供的功能。)
所以这是我的问题:当你为一个常数重新分配一个值时,你会得到一个警告:
>> FOO = 'bar'
=> "bar"
>> FOO = 'baz'
(irb):2: warning: already initialized constant FOO
=> "baz"
有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会重新分配。
答案 0 :(得分:5)
查看Can you ask ruby to treat warnings as errors?,了解在某些情况下如何将警告视为错误。
否则我猜你必须编写一个自定义方法来分配常量并在已经分配的情况下引发异常。
如果您知道特定常量的重新分配,您还可以在分配之前添加健全性检查。
答案 1 :(得分:3)
你不能直接拦截它,不。
如果真的需要这样做,我可以想到一个非常肮脏的黑客。您可以将标准错误IO重定向到自定义IO对象。然后write
方法可以检查正在写的内容;如果它包含"warning: already initialized constant"
,那么你加注,否则你将调用转发给标准错误write
。
答案 2 :(得分:1)
如果常量在类或模块中,那么你可以freeze
类或模块:
# Normal scenario
$VERBOSE = true
class Foo
BAR = 1
end
Foo::BAR = 2 # warning: already initialized constant BAR
# Using freeze
Foo.freeze
Foo::BAR = 3
RuntimeError: can't modify frozen Class
from (irb):8
from /Users/agrimm/.rbenv/versions/1.9.3-p194/bin/irb:12:in `<main>'
对于您的方案,您可以冻结Object
,但这听起来有些可怕。