4

I have the following class:

class Register
  attr_accessor :val
  def initialize
    @val = 0
  end
end

I wish to be able to, given ax=Register.new, type 3 + ax or ax + 3 and get as a result the equivalent of 3 + ax.val. I tried searching but can't find how this is done in Ruby.

  • 1
    Why would you want to? What's wrong with using ax.val, which is unambiguous and works in the desired fashion? – pjs Jan 12 '14 at 22:37
  • The way I worded it,it does sound unneeded, but what I want this for is to be able to add together `Register`s with either `Fixnum`s or other `Register`s. So I need to be able to do both `ax + 3` and `ax + bx`, which, if using `val`, will not work for `Fixnum`s. – Tsani Prodanov Jan 12 '14 at 22:47
  • 1
    Still not seeing why `ax.val + 3` or `ax.val + bx.val` wouldn't be sufficient. – pjs Jan 12 '14 at 22:50
  • If I do this in a method and want to add a variable, say `addend`, I will have to do a conditional statement on that variable, because I don't know if I want `addend` or `addend.val`. And I want to try to avoid that. It's for educational purposes. – Tsani Prodanov Jan 12 '14 at 22:53

2 Answers2

4

For ax + 3 to work, you need to define + method on your class:

def +(other)
  @value + other
end

However, 3 + x will still result in an error as the interpreter won't have clue how to combine a Fixnum with the instance of your class. To fix this, define the coerce method like this:

def coerce(other)
  if other.is_a?(Fixnum)
    [other, @value]
  else
    super
  end
end

I won't go into detail on how coerce works as we already have a great answer here.

Community
  • 1
  • 1
mechanicalfish
  • 12,696
  • 3
  • 46
  • 41
0

You can add the method to the class:

class Register
  attr_accessor :val
  def initialize
    @val = 0
  end

  def +(x)
    @val + x
  end
end

a = Register.new
a + 5 # => 5

Note that, this method will allow you to call a + 5 but not 5 + a. You will get a TypeError: Register can't be coerced into Fixnum if you try.

Mohamad
  • 34,731
  • 32
  • 140
  • 219