我想用来value.respond_to?(:dup) ? value.dup : value检查我是否可以复制一个对象,但它失败了,TypeError在booleans,nil或类似的"原语"上.
我最终得到了:
begin
value = value.dup
rescue
#ignore, use the original if no dup-able (e.g nil, true, etc)
end
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?
额外奖励:为什么会回应:dup?
不深dup,仅针对这个问题.
编辑:思考:
obj.class.methods.include? :new 很好,但有点过于hackish我觉得它有糟糕的表现 Marshal 看起来也有点矫枉过正dup在对象级别定义是错误的.所以,引用@Linuxios
没有更好的方法
您可以通过这种方式将其写为一行:
value = value.dup rescue value
Run Code Online (Sandbox Code Playgroud)
非常清楚.
定义一种为无法复制的类型dup引发的方法是标准的TypeError.因此任何对象都会"回应"它.你真的要打电话给它,并检查开始救援结束.
没有更好的方法.dup在Object上定义,这意味着任何想要不响应它的类都需要重载它以引发异常.NilClass,TrueClass,FalseClass,和Number是对象的所有子类.这意味着他们必须覆盖该方法以抛出错误.
解决这个问题的一种方法,如果你正在寻找一个深层复制品,就是使用通常Marshal.load(Marshal.dump(obj))会处理数字,bool和nil就好了.
例如:
1.9.3-p392 :001 > obj = "hi"
=> "hi"
1.9.3-p392 :002 > Marshal.load(Marshal.dump(obj)).object_id != obj.object_id
=> true
1.9.3-p392 :003 > obj = 3
=> 3
1.9.3-p392 :004 > Marshal.load(Marshal.dump(obj)).object_id != obj.object_id
=> false
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
490 次 |
| 最近记录: |