NoMethoError is raised by
to_i simply because the class doesn't have the method:
.to_i # >> NoMethodError (undefined method `to_i' for :Array)
1i has the method
to_f, so it responds to them. But in reality this looks very tricky.
1i.respond_to?(:to_i) # => true 1i.to_i # >> RangeError (can't convert 0+1i into Integer)
From where does the
Range class come in here?
Surely enough, 1i has the method .to_i and .to_f so it responds to them. But in reality this looks very tricky!
Yes, it responds to them. And when you invoke
to_i on the complex literal
1i, that method throws a
RangeError. That has nothing to do with the
Range class; it is telling you that although
1i has a
to_i method from class
Complex, its specific value is not one for which a meaningful result can be obtained.
Or to put it another way, that's what
Complex::to_i does when invoked on an object whose imaginary part is nonzero or even inexact:
to_i → integer
Returns the value as an integer if possible (the imaginary part should be exactly zero).
Complex(1, 0).to_i #=> 1 Complex(1, 0.0).to_i # RangeError Complex(1, 2).to_i # RangeError
RangeError communicates roughly that an argument is outside the range of the function to which it was provided, i.e. in the mathematical sense of "range".
Complex is a bit unusual in applying that sense of "range" to the target object, as opposed to a method argument, but it nevertheless makes sense.