NoMethoError
由to_i
引发,仅仅是因为该类没有方法:
[].to_i # >> NoMethodError (undefined method `to_i' for []:Array)
当然,1i
拥有方法to_i
和to_f
,因此它可以对它们做出响应。但实际上,这看起来很棘手。
1i.respond_to?(:to_i) # => true
1i.to_i # >> RangeError (can't convert 0+1i into Integer)
Range
类从何而来?
答案 0 :(得分:9)
当然,1i拥有方法.to_i和.to_f,因此它可以对它们进行响应。但是实际上,这看起来非常棘手!
是的,它会回应他们。当您在复杂文字to_i
上调用1i
时,该方法将抛出RangeError
。这与Range
类无关;它告诉您,尽管1i
具有类to_i
的{{1}}方法,但是它的特定值并不是可以获取有意义结果的值。
或者换句话说,Complex::to_i
在虚部不为零甚至不精确的对象上调用时就是这样做的:
to_i→整数
如果可能,将值返回为整数(虚数部分应 完全为零)。
Complex
Complex(1, 0).to_i #=> 1
Complex(1, 0.0).to_i # RangeError
Complex(1, 2).to_i # RangeError
粗略地传达了一个论点在提供该论点的函数范围之外,即在数学意义上为“范围”。 RangeError
与目标方法相比,在将“范围”意义应用于目标对象时有点不寻常,但这仍然是有道理的。
答案 1 :(得分:2)
文档所说的是
Returns the value as an integer if possible (the imaginary part should be exactly zero).
因此,它看起来并不太有用,它仅在i
为零时有效。
答案 2 :(得分:2)
Complex#to_i
的规范如Ursus和John Bolinger在回答中所说。
定义Complex#to_i
的原因(因此不会引发NoMethoError
错误)是因为当虚部不为零时它返回计算值,因此需要对其进行定义。您不能仅针对某个类的实例引发NoMethodError
。
之所以没有引发更熟悉的异常(例如ArgumentError
),是因为它不是参数,而是接收者。
要针对某个类的某些实例引发错误,最合适的方法是RangeError
;没有其他Exception
类似乎更合适。