Ivor Horton
Ivor Horton

Reputation: 77

What's wrong with below ruby coerce method?

Below is the code.

class Fixnum
  def coerce o
    p o
    p self
    [o.to_a, self]
  end
end

p ((1..10) << 14)

What I want is when I call << on a Range object, I'll convert the Range to an Array and append the object to it. The code does not work as I expected and I need some advice.


Update:

Thanks guys for the comments. Actually I'm not doing monkey-patch for some particular intentions and I just want to lean the mechanism behind the coerce method. I've done something below.

[26] pry(main)> 1 + "3"
TypeError: String can't be coerced into Fixnum
from (pry):24:in `+'
[27] pry(main)> class String
[27] pry(main)*   def coerce o
[27] pry(main)*     [o, self.to_i]
[27] pry(main)*   end
[27] pry(main)* end
=> nil
[28] pry(main)> 1 + "3"
=> 4
[29] pry(main)>

From my understand I'm doing almost the same thing with my first example and it works. I still can't see the difference between those two examples and I need a pair of eagle eyes.


Update 2

To make my problem clear I've refactored my first example to:

C:\>pry
[1] pry(main)> (1..10) << 14
NoMethodError: undefined method `<<' for 1..10:Range
from (pry):1:in `__pry__'
[2] pry(main)> class Fixnum
[2] pry(main)*   def coerce o
[2] pry(main)*     [o.to_a, self]
[2] pry(main)*   end
[2] pry(main)* end
=> nil
[3] pry(main)> (1..10) << 14
NoMethodError: undefined method `<<' for 1..10:Range
from (pry):7:in `__pry__'
[4] pry(main)> [1, 2, 3] << 4
=> [1, 2, 3, 4]
[5] pry(main)>

Upvotes: 0

Views: 169

Answers (1)

ptd
ptd

Reputation: 3053

I think what you want is to add the << method to the Range class.

class Range
  def <<(o)
    self.to_a << o
  end
end

Since you want to put << after an instance of a Range, you need to add such a method to the Range class. This will then return an array with the passed in item appended.

Upvotes: 4

Related Questions