我想使用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是在对象上定义的,这意味着任何不想响应它的类都需要重载它来抛出异常。NilClassTrueClassFalseClassNumber都是对象的子类。这意味着他们必须重写方法来抛出错误。
解决这个问题的一种方法是,如果您正在寻找一个深拷贝,那么使用通常的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/

10-11 01:36