在Ruby中重新分配常量时抛出exception?
我早就意识到Ruby中的“常量”(即大写的变量名)并不是真正的常量。 与其他编程语言一样,对象的引用是唯一存储在变量/常量中的东西。 (补充工具栏:Ruby确实具有“冻结”被修改引用对象的function,据我所知,这不是许多其他语言提供的能力。)
所以这是我的问题:当你为一个常量重新赋值时,你得到一个警告:
>> FOO = 'bar' => "bar" >> FOO = 'baz' (irb):2: warning: already initialized constant FOO => "baz"
有没有办法强制Ruby抛出exception而不是打印警告? 很难弄清楚为什么有时会进行重新分配。
请查看此问题 ,了解在某些情况下如何将警告视为错误。
否则,我猜你必须编写一个自定义方法来分配常量,并在已经分配的情况下引发exception。
如果您知道重新分配发生在特定常量上,您还可以在分配之前添加一个完整性检查。
你不能直接拦截它,不。
如果你真的需要这样做,我可以想到一个非常肮脏的黑客。 您可以将标准错误IO重定向到自定义IO对象。 然后, write
方法可以检查正在写入的内容; 如果它包含"warning: already initialized constant"
,那么你加注,否则你将调用转发到标准错误的write
。
如果常量在类或模块中,那么您可以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 `'
对于您的场景,您可以冻结Object
,但这听起来有点可怕。
- 设计身份validation – devise_error_messages! 在一个视图中导致nil的“未定义的方法`错误”:NilClass
- 替代“救援exception”
- Hoptoad诉Exceptional诉exception_notification诉exception_logger案
- delayed_job的exception_notification
- Rails ActiveJob – 在ActionMailer :: DeliveryJob中处理exception的好方法是什么
- Devise中的InvalidAuthenticityToken :: SessionsController#destroy(已经注销后退出)
- 如何让这个动作抛出404?
- Ruby中的失败与提升:我们真的应该相信风格指南吗?
- 是否可以从事务块内重新引发ActiveRecord :: Rollbackexception?