0

I want to define a custom :+= method on my Ruby class that modifies the instance. However, the following code raises syntax error, unexpected '=', expecting ';' or '\n'

def +=(other)
  @value += other.to_f
end

What are my options here? I see that Fixnum has :+@ and :-@ methods, but I don't exactly see what they do in the documentation. Are those the methods I want to write?

2
  • defining :+@ actually redefines the entire object to be a Float, rather than update the instance variable, as I intended. Commented Apr 24, 2014 at 19:19
  • Duplicate of this question, which has a good answer. Commented Apr 24, 2014 at 19:28

2 Answers 2

5

Unlike C++ or other languages with robust overrides, there's no such method as += in Ruby.

What's happening internally is a sort of expansion. For example:

x += n

If x is a variable, then this is equivalent to:

x = x.send(:+, n)

If x= is defined, then this is equivalent to:

send(:x=, x.send(:+, n))

Whatever you need to do to override must be to redefine x= or + on the class of x.

Remember that the + method should not modify x. It's supposed to return a copy of x with the modification applied. It should also return an object of the same class of x for consistency.

Your method should look like:

def +(other)
  # Create a new object that's identical in class, passing in any arguments
  # to the constructor to facilitate this.
  result = self.class.new(...)

  result.value += other.to+f

  result
end
Sign up to request clarification or add additional context in comments.

4 Comments

Gotcha (on the last part). That's what I have for the base :+ method. I want to be able to perform all 4 basic arithmetic operations, and their destructive forms on this object. I'm confused how to implement that internal expansion, if that makes any sense
Remember that the + method should not modify x. It's supposed to return a copy of x with the modification applied. I agree with this, but I wonder if you have any kind of reference?
Whatever you've got to do to return a copy of the object with the modification applied, you do that. @emaillenin has an answer below with another type of example.
@tadman Got it! I just had to write up both forms of the method and inspect the process step by step to understand. Thanks so much!
1

I am not really sure, but you do not need the = operator.

def +(other)
  @value += other.to_f
end

Example from here:

class Money
  attr_accessor :value

  def +(b)
    result = dup
    result.value += b.value
    return result
  end

  def -(b)
    result = dup
    result.value += b.value
    return result
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.