Operator Overloading

Let's suppose I have a class like this one and then I create two
objects:

···

=-=-=-=-=-=-=-=-=-=-=-=
class Point

  def initialize
    x = 5
    y = 10
    z = 25
  end

end

a = Point.new
b = Point.new
=-=-=-=-=-=-=-=-=-=-=-=

How do I do if I want to add a and b together to a new point called c?
Example:

c = a + b

How exactly should I implement the operator overloading feature? So that
x = 10, y = 20, z = 50. There are hardly any tutorial for this...

Thank you!

--
Posted via http://www.ruby-forum.com/.

Ruby doesn't do operator overloading. But that doesn't matter, since
"+" is a method. Thus:

class Point
  def self.+(obj)
     # Details of addition
  end
end

···

On Tue, Oct 4, 2011 at 7:11 AM, Thescholar Thescholar <thescholar@hotmail.ca> wrote:

Let's suppose I have a class like this one and then I create two
objects:

=-=-=-=-=-=-=-=-=-=-=-=
class Point

def initialize
x = 5
y = 10
z = 25
end

end

a = Point.new
b = Point.new
=-=-=-=-=-=-=-=-=-=-=-=

How do I do if I want to add a and b together to a new point called c?
Example:

c = a + b

How exactly should I implement the operator overloading feature? So that
x = 10, y = 20, z = 50. There are hardly any tutorial for this...

--
Phillip Gawlowski

gplus.to/phgaw | twitter.com/phgaw

A method of solution is perfect if we can forsee from the start,
and even prove, that following that method we shall attain our aim.
-- Leibniz

class Point
  def +(other)
    #there your code, i think
    result = Point.new
    result.x = self.x + other.x
    result.y = self.y + other.y
    result.z = self.z + other.z
    return result
  end
end

but you also need to make the variables accessable like
class Point
  attr_accessor :x,:y,:z
end

and you should remove your init, it is wrong

···

--
Posted via http://www.ruby-forum.com/.

class Point
  attr_accessor :x, :y, :z

def initialize(x=5, y=10, z=25)
   self.x = x
   self.y = y
   self.z = z
end

def +(point)
   Point.new x+point.x, y+point.y, z+point.z
end

def inspect
   "(#{x}, #{y}, #{z})"
end
end

a = Point.new
b = Point.new

a # => (5, 10, 25)
b # => (5, 10, 25)
a + b # => (10, 20, 50)

···

On Tue, Oct 4, 2011 at 12:11 AM, Thescholar Thescholar < thescholar@hotmail.ca> wrote:

Let's suppose I have a class like this one and then I create two
objects:

=-=-=-=-=-=-=-=-=-=-=-=
class Point

def initialize
   x = 5
   y = 10
   z = 25
end

end

a = Point.new
b = Point.new
=-=-=-=-=-=-=-=-=-=-=-=

How do I do if I want to add a and b together to a new point called c?
Example:

c = a + b

How exactly should I implement the operator overloading feature? So that
x = 10, y = 20, z = 50. There are hardly any tutorial for this...

Thank you!

--
Posted via http://www.ruby-forum.com/\.

For a full blown example you can look here:
http://blog.rubybestpractices.com/posts/rklemme/019-Complete_Numeric_Class.html

Kind regards

robert

···

On Tue, Oct 4, 2011 at 7:11 AM, Thescholar Thescholar <thescholar@hotmail.ca> wrote:

Let's suppose I have a class like this one and then I create two
objects:

=-=-=-=-=-=-=-=-=-=-=-=
class Point

def initialize
x = 5
y = 10
z = 25
end

end

a = Point.new
b = Point.new
=-=-=-=-=-=-=-=-=-=-=-=

How do I do if I want to add a and b together to a new point called c?
Example:

c = a + b

How exactly should I implement the operator overloading feature? So that
x = 10, y = 20, z = 50. There are hardly any tutorial for this...

Thank you!

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Let's suppose I have a class like this one and then I create two
objects:

=-=-=-=-=-=-=-=-=-=-=-=
class Point

  def initialize
    x = 5
    y = 10
    z = 25
  end

This won't work since x, y and z in the above are local to the
constructor. So those variables will be lost when the constructor exits.

end

a = Point.new
b = Point.new
=-=-=-=-=-=-=-=-=-=-=-=

How do I do if I want to add a and b together to a new point called c?
Example:

c = a + b

How exactly should I implement the operator overloading feature? So that
x = 10, y = 20, z = 50. There are hardly any tutorial for this...

Define a + method on your Point class:

def +(other)
  self.x += other.x
  self.y += other.y
  self.z += other.z
  self
end

That last line is IMPORTANT. Remember, Ruby methods treat the last value
evaluated in a method as the return value. So if you don't put self in
then the return value for the + method will be the last addition.

So now with the above:

c = a + b

is the equivalent of doing:

c = a.+(b)

HTH.

···

On 10/04/2011 01:11 AM, Thescholar Thescholar wrote:

--
Darryl L. Pierce <mcpierce@gmail.com>
http://mcpierce.multiply.com/
"What do you care what people think, Mr. Feynman?"

class Point
  def +(other)
    #there your code, i think
    result = Point.new
    result.x = self.x + other.x
    result.y = self.y + other.y
    result.z = self.z + other.z
    return result
  end
end

but you also need to make the variables accessable like
class Point
  attr_accessor :x,:y,:z
end

And add '@' to them in the constructor.

···

On 10/04/2011 01:23 AM, Hans Mackowiak wrote:

and you should remove your init, it is wrong

--
Darryl L. Pierce <mcpierce@gmail.com>
http://mcpierce.multiply.com/
"What do you care what people think, Mr. Feynman?"

Darryl Pierce wrote in post #1024950:

Define a + method on your Point class:

def +(other)
  self.x += other.x
  self.y += other.y
  self.z += other.z
  self
end

Warning!! That will *mutate* the point passed as the left-hand argument
of the '+'!

I would suggest instead:

def +(other)
  Point.new(x+other.x, y+other.y, z+other.z)
end

(Of course, 'x' and 'self.x' are the same; you can write 'self.x' if you
think it's clearer)

···

--
Posted via http://www.ruby-forum.com/\.

Darryl Pierce wrote in post #1024950:

Define a + method on your Point class:

def +(other)
  self.x += other.x
  self.y += other.y
  self.z += other.z
  self
end

Warning!! That will *mutate* the point passed as the left-hand argument
of the '+'!

I would suggest instead:

def +(other)
  Point.new(x+other.x, y+other.y, z+other.z)
end

DOH! Good point!

(Of course, 'x' and 'self.x' are the same; you can write 'self.x' if you
think it's clearer)

I don't think so. 'x' is a local variable, while '@x' is an instance
variable. And since the fields are instance variables they have to be
prefixed with '@'.

···

On 10/04/2011 10:03 AM, Brian Candler wrote:

--
Darryl L. Pierce <mcpierce@gmail.com>
http://mcpierce.multiply.com/
"What do you care what people think, Mr. Feynman?"

Not quite. This is one of Ruby's little gotchas. A naked "x" will be
taken as a local variable in the method. If you want to use an
instance variable you *must* precede it with either "self." or "@".

-Dave

···

On Tue, Oct 4, 2011 at 10:03, Brian Candler <b.candler@pobox.com> wrote:

(Of course, 'x' and 'self.x' are the same; you can write 'self.x' if you
think it's clearer)

--
LOOKING FOR WORK, preferably Ruby on Rails, in NoVa/DC; see main web site.
Main Web Site: davearonson.com
Programming Blog: codosaur.us
Excellence Blog: dare2xl.com

Not quite. :slight_smile:

class Foo
  attr_reader :x

  def initialize(x)
    @x = x
  end

  def bar
    x # :slight_smile:
  end
end

f = Foo.new(1)
puts f.bar

http://ideone.com/mbPc0

If there's no local variable in the scope, the interpreter sees it as a
method call. If it's ambiguous, it'll pick the variable over the method
call, unless you force it with a trailing ().

x = 1
def x; 2; end
puts x
puts x()

···

On Tue, Oct 4, 2011 at 3:53 PM, Darryl L. Pierce <mcpierce@gmail.com> wrote:

> (Of course, 'x' and 'self.x' are the same; you can write 'self.x' if you
> think it's clearer)

I don't think so. 'x' is a local variable, while '@x' is an instance
variable. And since the fields are instance variables they have to be
prefixed with '@'.

The story is a bit more complex.

1. writing

"x = exp" will _always_ assign to a local variable. If you want to
invoke the setter method you _must_ do "self.x = expr".

2. reading

"x" will access a local variable if it is defined and fall back to the
getter method if there is no variable. "self.x" will always invoke
the getter method regardless whether there is a local variable or not.

Example:

$ ruby19 -e 'def x;1;end;public :x;def f;p x, self.x;x=99;p x, self.x;end;f'
1
1
99
1

Needless to say that it's not the best of practices to mix local
variables and properties of the same name. :slight_smile:

Kind regards

robert

···

On Tue, Oct 4, 2011 at 5:52 PM, Dave Aronson <rubytalk2dave@davearonson.com> wrote:

On Tue, Oct 4, 2011 at 10:03, Brian Candler <b.candler@pobox.com> wrote:

(Of course, 'x' and 'self.x' are the same; you can write 'self.x' if you
think it's clearer)

Not quite. This is one of Ruby's little gotchas. A naked "x" will be
taken as a local variable in the method. If you want to use an
instance variable you *must* precede it with either "self." or "@".

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Sorry, Brian was right. Try it out in the context of the code sample he
posted to see for yourself.

···

On 10/04/2011 11:52 AM, Dave Aronson wrote:

On Tue, Oct 4, 2011 at 10:03, Brian Candler <b.candler@pobox.com> wrote:

(Of course, 'x' and 'self.x' are the same; you can write 'self.x' if you
think it's clearer)

Not quite. This is one of Ruby's little gotchas. A naked "x" will be
taken as a local variable in the method. If you want to use an
instance variable you *must* precede it with either "self." or "@".

--
Darryl L. Pierce <mcpierce@gmail.com>
http://mcpierce.multiply.com/
"What do you care what people think, Mr. Feynman?"

Okay, then this flies in the face of how I understood variables. I would
have thought the act of having 'x' in the definition for bar in the
above created a local variable in the current scope.

···

On 10/04/2011 11:11 AM, Adam Prescott wrote:

(Of course, 'x' and 'self.x' are the same; you can write 'self.x' if you
think it's clearer)

I don't think so. 'x' is a local variable, while '@x' is an instance
variable. And since the fields are instance variables they have to be
prefixed with '@'.

Not quite. :slight_smile:

class Foo
  attr_reader :x

  def initialize(x)
    @x = x
  end

  def bar
    x # :slight_smile:
  end
end

f = Foo.new(1)
puts f.bar

http://ideone.com/mbPc0

If there's no local variable in the scope, the interpreter sees it as a
method call. If it's ambiguous, it'll pick the variable over the method
call, unless you force it with a trailing ().

x = 1
def x; 2; end
puts x
puts x()

--
Darryl L. Pierce <mcpierce@gmail.com>
http://mcpierce.multiply.com/
"What do you care what people think, Mr. Feynman?"

"x" will access a local variable if it is defined and fall back to the
getter method if there is no variable. "self.x" will always invoke
the getter method regardless whether there is a local variable or not.

x() too, as an alternative to self.x. Although I prefer the latter.

Needless to say that it's not the best of practices to mix local
variables and properties of the same name. :slight_smile:

+1!

···

On Tue, Oct 4, 2011 at 4:58 PM, Robert Klemme <shortcutter@googlemail.com>wrote:

My understanding (probly flawed) is
attr_reader :x

generates the following code:

def x
  @x
end

so in bar that 'x' is a call to the x method, which returns the '@x' value
but doing it this way makes the x public readable, so should only be
used if that is needed
I'd stick with using @x

Only an assignment creates a local variable in the scope.

def bar
  x = 2
end

This creates a local variable x in the method bar. If there are no
assignments, the parser understands that references to x must be
method calls. This is due to the syntax ambiguity between methods and
local variables, because ruby allows you to call methods without
parens. So, to break the ambiguity, the parser marks references as
methods by default, and only as local variables when it sees an
assignment.

Jesus.

···

On Tue, Oct 4, 2011 at 5:31 PM, Darryl L. Pierce <mcpierce@gmail.com> wrote:

On 10/04/2011 11:11 AM, Adam Prescott wrote:

(Of course, 'x' and 'self.x' are the same; you can write 'self.x' if you
think it's clearer)

I don't think so. 'x' is a local variable, while '@x' is an instance
variable. And since the fields are instance variables they have to be
prefixed with '@'.

Not quite. :slight_smile:

class Foo
attr_reader :x

def initialize(x)
@x = x
end

def bar
x # :slight_smile:
end
end

f = Foo.new(1)
puts f.bar

http://ideone.com/mbPc0

If there's no local variable in the scope, the interpreter sees it as a
method call. If it's ambiguous, it'll pick the variable over the method
call, unless you force it with a trailing ().

x = 1
def x; 2; end
puts x
puts x()

Okay, then this flies in the face of how I understood variables. I would
have thought the act of having 'x' in the definition for bar in the
above created a local variable in the current scope.

This is actually only 1/7th true. There are as many as 7 ways to
introduce a new variable, out of which anybody would guess about 5 if
they though about it for a while ;), and 2 are quite obscure.

These are:

1. Single- or multiple-assignment (including sub-assignment) anywhere
an expression is allowed
2. A for loop's iterator variable(s)
3. Formal arguments to a method
4. Block arguments and block-local variables
5. Stabby Lambda variables
6. Rescue exception naming (rescue StandardError => err)
7. Named Regexp captures in literal matches (/name: (?<person>\w+)/ =~
'name: Mike' creates a local variable named "person" with value
"Mike")

(The above borrowed from https://github.com/michaeledgar/ripper-plus\)

Ah, the joys of high-level programming :smiley:

-- Matma Rex

···

2011/10/4 Jesús Gabriel y Galán <jgabrielygalan@gmail.com>:

Only an assignment creates a local variable in the scope.

AH! That's what I missing, and what he meant by "the method". Okay. The
OP though didn't have the attr_accessor on the fields, though, that I
remember.

···

On 10/04/2011 11:42 AM, Chris Hulan wrote:

My understanding (probly flawed) is
attr_reader :x

generates the following code:

def x
  @x
end

so in bar that 'x' is a call to the x method, which returns the '@x' value
but doing it this way makes the x public readable, so should only be
used if that is needed
I'd stick with using @x

--
Darryl L. Pierce <mcpierce@gmail.com>
http://mcpierce.multiply.com/
"What do you care what people think, Mr. Feynman?"

Only an assignment creates a local variable in the scope.

This is actually only 1/7th true. There are as many as 7 ways to
introduce a new variable, out of which anybody would guess about 5 if
they though about it for a while ;), and 2 are quite obscure.

These are:

1. Single- or multiple-assignment (including sub-assignment) anywhere
an expression is allowed
2. A for loop's iterator variable(s)

Kind of assignment :slight_smile:

3. Formal arguments to a method

Good one, I was thinking only in the body of the method, but you can
also argue that someone does an assignment to them :slight_smile:

4. Block arguments and block-local variables

Block arguments and block local variables are local to the block
scope, not the method.

5. Stabby Lambda variables

What do you mean by this?

6. Rescue exception naming (rescue StandardError => err)

Kind of assignment :slight_smile:

7. Named Regexp captures in literal matches (/name: (?<person>\w+)/ =~
'name: Mike' creates a local variable named "person" with value
"Mike")

Didn't knew this one, thanks.

Jesus.

···

2011/10/4 Bartosz Dziewoński <matma.rex@gmail.com>:

2011/10/4 Jesús Gabriel y Galán <jgabrielygalan@gmail.com>: