On Mon, Sep 27, 2010 at 8:49 PM, Trevor Hinesley
<trevor.hinesley / gmail.com> wrote:
> 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)
> =A0return -a
> end
> b =3D 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 =3D 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 =3D 2; puts -n" would work.

Finally, 2 and 4 are Fixnums, not instances of Overloading. Perhaps
you're confused because you have "b =3D 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 =3D 2-4
  puts "#{b}" # prints 6
end


# OR


class Fixnum
  # Redefined unary minus
  def -@
    return self
  end

  b =3D 2 + -(4)
  puts "#{b}" # prints 6
end


# OR



class Overloading
  attr_accessor :value

  def initialize(value)
    @value =3D value
  end

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

  b =3D Overloading.new(2) - Overloading.new(4)
  puts "#{b.value}" # prints 6
end