是否有可能改变Ruby的冻结对象处理行为?

时间:2013-10-19 11:57:59

标签: ruby

我正在codewars.com上提交解决Ruby谜题的解决方案,并试验如何锁定测试环境我是其中一个挑战。

我可以重新定义用于测试我的解决方案的类,但它们是在我提交代码后由系统定义的。如果我冻结这些对象,系统无法覆盖它们,但在尝试时会引发RunTime错误。

我对Ruby很新,所以我不确定哪些部分(除了虚假和真实性)都无法覆盖。我是否可以使用Ruby代码来强制修改冻结的对象以静默方式失败而不是终止程序,还是绑定在诸如赋值运算符之类的不可触及的东西中?

1 个答案:

答案 0 :(得分:0)

这里真正的答案是,如果您以后想要修改某个对象,则不应该冻结它。这是“冻结”一个物体的整个概念所固有的。但是,既然你问过,请注意你可以测试对象是否被冻结:

 obj.frozen?

因此,如果那些讨厌的RuntimeError让你失望,一个解决方案是使用一个保护条款,如:

 obj.do_something! if !obj.frozen?

如果你想隐含保护条款,你可以使用猴子补丁重新定义“问题”方法:

 class Array
   # there are a couple other ways to do this
   # read up on Ruby metaprogramming if you want to know
   alias :__pop__ :pop
   def pop
     frozen? ? nil : __pop__
   end
 end

如果您希望您的代码与任何和所有Ruby库/ gem无缝地协作,那么向这样的内置方法添加行为可能是一个坏主意。在这种情况下,我怀疑它会导致任何问题,但是每当你选择开始攻击Ruby的核心类时,你必须为可能的后果做好准备。