Operator Overload

Hey guys,

I’m slowly getting the hang of Ruby, I’m a Java guy by trade. I really
like Ruby and am picking up on it pretty quickly, but for some reason my
overload of the “+” operator is not working. Here is the code:

class Overloading
def -(a)
return -a
end
b = 2-4
puts “#{b}”
end

Basically, I’m trying to turn the minus operator into a plus operator
for a project to show how operator overloading in Ruby works, but this
isn’t working from some reason, and I’m not sure why.

Help?

Thanks,

Trevor

On Sep 27, 9:49 pm, Trevor H. [email protected] wrote:

b = 2-4

Trevor

Posted viahttp://www.ruby-forum.com/.

I think you have just defined the class called Overloading and have
not instantiated it. Did you intend to do this?
class Overloading
def -(a)
return -a
end
b = 2-4
puts “#{b}”
end

x = Overloading.new
puts “#{x.-(5)}”
puts “#{x - 5}” # same as x.-(5) above

Output:
-2 # this comes from the puts that is part of class definition
-5
-5

Well, the problem is it isn’t doing what I want it to.

It just prints -2, when I need it to print 6, since I’m wanting minus to
become plus basically.

When I do 2-4, I want it to do 2 minus negative four, which will give
six.

On 09/27/2010 10:04 PM, Trevor H. wrote:

Well, the problem is it isn’t doing what I want it to.

It just prints -2, when I need it to print 6, since I’m wanting minus to
become plus basically.

When I do 2-4, I want it to do 2 minus negative four, which will give
six.

You’re trying to treat minus as the unary version of the operator, but
in this usage it is the binary operator. It also appears from your
example that you are trying to overload it for all numbers using a
non-number class named Overloading. Since you’re able to get it to
return -2 in your test, I assume that you have actually managed to
overload the operator for at least the Fixnum class.

Try the following:

class Fixnum
def -(other)
self + other
end
end
b = 2 - 4
puts b

On 09/28/2010 03:49 AM, Trevor H. wrote:

b = 2-4
puts “#{b}”
end

Basically, I’m trying to turn the minus operator into a plus operator
for a project to show how operator overloading in Ruby works, but this
isn’t working from some reason, and I’m not sure why.

Help?

This might be interesting for you:

http://blog.rubybestpractices.com/posts/rklemme/019-Complete_Numeric_Class.html

Kind regards

robert

On Mon, Sep 27, 2010 at 8:49 PM, Trevor H.
[email protected] wrote:

b = 2-4
puts “#{b}”
end

Basically, I’m trying to turn the minus operator into a plus operator
for a project to show how operator overloading in Ruby works, but this
isn’t working from some reason, and I’m not sure why.

First, you’re not defining the + method – you’re defining -.

Second, your “b = 2-4” again uses the - method, not +.

Third, your implementation of - just returns negative a. I think
your understanding is that the expression “x - y” is implicitly
translated into “x + -y”; this isn’t so. “x - y” is translated into
“x.-(y)”, which in this case just returns -y, while ignoring x.

Fourth, if you want to define a unary minus method, you would do
something like:
def -@
self
end

I just realized that -@ doesn’t override the unary minus in literal
expressions like “-2”; it only works if you type “-(2)”. It seems that
if you use a variable, however, the parentheses are not required; thus
“n = 2; puts -n” would work.

Finally, 2 and 4 are Fixnums, not instances of Overloading. Perhaps
you’re confused because you have “b = 2 - 4” inside your Overloading
class; nevertheless, they are still Fixnums, and the - method you’ve
defined only applies to Overloading. Your - method will only be
invoked if the object on its left side is an Overloading instance. You
can redefine the operator methods on Fixnum, but it isn’t recommended.

So, maybe what you meant was something like one of these:

class Fixnum

Redefined minus

def -(a)
return self + a
end

b = 2-4
puts “#{b}” # prints 6
end

OR

class Fixnum

Redefined unary minus

def -@
return self
end

b = 2 + -(4)
puts “#{b}” # prints 6
end

OR

class Overloading
attr_accessor :value

def initialize(value)
@value = value
end

Redefined minus

def -(other)
return Overloading.new(@value + other.value)
end

b = Overloading.new(2) - Overloading.new(4)
puts “#{b.value}” # prints 6
end

Robert, I get the point. However it’s important to notice that there’s
no such
thing as operator overloading in Ruby. Things like :+, :-, :*, etc, are
just
plain methods. You can achieve what you want by opening the Fixnum class
and
redefining the method :+. Important to say is that all instances of this
will be
affected as soon as you make the change.

Eg:

class Fixnum
def -(x)
self + x
end
end

puts 1 - 1 # => 2

Another tip: In Ruby, every expression returns a value, so there’s no
need to
explicit the ‘return’.

Regards,

Adriano


From: Robert K. [email protected]
To: ruby-talk ML [email protected]
Sent: Thu, September 30, 2010 3:10:35 AM
Subject: Re: Operator Overload

On 09/28/2010 03:49 AM, Trevor H. wrote:

b = 2-4
puts “#{b}”
end

Basically, I’m trying to turn the minus operator into a plus operator
for a project to show how operator overloading in Ruby works, but this
isn’t working from some reason, and I’m not sure why.

Help?

This might be interesting for you:

http://blog.rubybestpractices.com/posts/rklemme/019-Complete_Numeric_Class.html

Kind regards

robert

Please do not top post.

On Fri, Oct 1, 2010 at 3:09 PM, Adriano F. [email protected]
wrote:

Robert, I get the point. However it’s important to notice that there’s no such
thing as operator overloading in Ruby. Things like :+, :-, :*, etc, are just
plain methods.

Adriano, operator “+” and all others are certainly overloaded (as in
many programming languages btw) because different implementations get
called depending on the left hand type. Method #coerce is just a way
to get double dispatch working.

You can achieve what you want by opening the Fixnum class and

I do not want something in particular (at least for the sake of this
thread) so I am not sure what you refer to.

redefining the method :+. Important to say is that all instances of this will be
affected as soon as you make the change.

This is precisely the reason to properly implement operators and
#coerce in new classes that should play nicely with existing classes.

Eg:

class Fixnum
def -(x)
self + x
end
end

puts 1 - 1 # => 2

This is certainly not something I would want.

Another tip: In Ruby, every expression returns a value, so there’s no need to
explicit the ‘return’.

Yes, I know. As far as I can see in my blog article there is no
“return” in the code.

Cheers

robert