一个对象可以`respond_to`一条消息,但在调用时会引发错误?

时间:2016-01-03 06:07:14

标签: ruby clone deep-copy

我试过了:

1.respond_to? "clone"    # => true
1.clone                  # => TypeError: can't clone Fixnum

似乎一个对象可以报告它接受一条消息,但是右边会引发异常。

我正在尝试写一个deep_copy。是否有一个内置的或可以一些代码片段已经这样做?如果我需要决定某些东西是否可克隆,我是否需要以任何方式调用它,然后从异常中rescue知道它不是?

如果某个对象会引发异常,那么(1)报告false是否有意义,或者是由于Object提出的接口要求,以及(2)我是否可以实际上告诉任何对象向respond_to "foo"报告错误?

3 个答案:

答案 0 :(得分:1)

从Jordan的评论中创建社区维基回答

Fixnum回复clone,因此1.respond_to?(:clone)返回true是有意义的。

如果您使用方法

编写了一个类,请考虑一下
def foo
   raise "Error!" 
end

您希望该类的实例为true返回respond_to(:foo)?。答案是“是”。

是否引发错误并不重要。如果它提出一个没有意义的NoMethodError,但这不是这里的情况。

答案 1 :(得分:1)

考虑:

Fixnum.instance_method(:clone).owner
  #=> Kernel
Fixnum.ancestors
  #=> [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
Fixnum.included_modules
  #=> [Comparable, Kernel]

Fixnum的实例响应所有Fixnum的实例方法,包括它从其祖先继承的那些方法。为了确保在Fixnum实例上调用每个方法(clone为1)时不会引发异常,该语言将需要不同的设计。

答案 2 :(得分:1)

respond_to? == true表示NoMethodError不会加注。

但其他错误可能会引发。

如果您想进行深度克隆,请使用

Marshal.load(Marshal.dump(obj_to_copy))