- A+

`NoMethoError`

is raised by `to_i`

simply because the class doesn't have the method:

`[].to_i # >> NoMethodError (undefined method `to_i' for []:Array) `

Surely enough, `1i`

has the method `to_i`

and `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 → integerReturns 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`

A `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.