我想使用value.respond_to?(:dup) ? value.dup : value
来检查是否可以复制一个对象,但在布尔、nil或类似的“原语”上使用TypeError
失败。
我的结局是:
begin
value = value.dup
rescue
#ignore, use the original if no dup-able (e.g nil, true, etc)
end
有更好的办法吗?
附加:为什么它会响应
:dup
?不是很深,只是为了这个问题。
编辑:想法:
dup
不错,但有点太老套了我觉得它的性能不好obj.class.methods.include? :new
看起来也有点过头了单线救援可能是最好的解决方案,但此时(IIUC matz is on that!)不可能进行特定类型的单线救援,正如@jórgwmittag提到的那样。
我个人认为在对象级别定义
Marshal
是错误的。所以,引用@linuxios
没有更好的办法了
最佳答案
没有更好的办法了。dup
是在对象上定义的,这意味着任何不想响应它的类都需要重载它来抛出异常。NilClass
、TrueClass
、FalseClass
和Number
都是对象的子类。这意味着他们必须重写方法来抛出错误。
解决这个问题的一种方法是,如果您正在寻找一个深拷贝,那么使用通常的Marshal.load(Marshal.dump(obj))
来处理数字、bools和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
关于ruby - 我如何检查变量是否真正响应:dup?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20954789/