How can two references to the same object behave differently?

  • Thread starter Just Another Victim of the Ambient Morality
  • Start date
J

Just Another Victim of the Ambient Morality

I've been having a lot of fun writing iTunes scripts with Ruby through
COM and have encountered behaviour I don't understand (what else is new).
The following code works just as you would expect:

iTunes = WIN32OLE.new('iTunes.Application')
iTunes.PlayerPosition = 50
iTunes.Play

...it starts playing the current song from position 50. However, you'd
think the following code would do exactly the same thing:

iTunes = WIN32OLE.new('iTunes.Application')
temp = iTunes.PlayerPosition
temp = 50
iTunes.Play

Okay, there are many languages where this would totally not do the same
thing but I thought that all variables in Ruby were references. So, the
assignment to temp should have made it refer to the same object that
iTunes.PlayerPosition returned.
So, what is going on? Why doesn't the second block of code work? Does
it have something to do with WIN32OLE or do I just have no idea how Ruby
works?
Thank you!
 
C

Claus Rasmussen

Just said:
I've been having a lot of fun writing iTunes scripts with Ruby through
COM and have encountered behaviour I don't understand (what else is new).
The following code works just as you would expect:

iTunes = WIN32OLE.new('iTunes.Application')
iTunes.PlayerPosition = 50
iTunes.Play

...it starts playing the current song from position 50. However,
you'd think the following code would do exactly the same thing:

iTunes = WIN32OLE.new('iTunes.Application')
temp = iTunes.PlayerPosition
temp = 50
iTunes.Play

iTunes.PlayPosition and temp initially refer to the same object (the integer
representing the current player position), but 'temp = 50' makes temp refer
to a /different/ object (the integer representing '50') while
iTunes.PlayPosition still refer to the original object.

It's no different from

a = 0
b = a
b = 50

p a # 0
p b # 50
 
D

Dave Burt

Just said:
I've been having a lot of fun writing iTunes scripts with Ruby through
COM and have encountered behaviour I don't understand (what else is new).
The following code works just as you would expect:

iTunes = WIN32OLE.new('iTunes.Application')
iTunes.PlayerPosition = 50
iTunes.Play

...it starts playing the current song from position 50. However, you'd
think the following code would do exactly the same thing:

iTunes = WIN32OLE.new('iTunes.Application')
temp = iTunes.PlayerPosition
temp = 50
iTunes.Play

Okay, there are many languages where this would totally not do the same
thing but I thought that all variables in Ruby were references. So, the
assignment to temp should have made it refer to the same object that
iTunes.PlayerPosition returned.

This is a method call:

foo.bar = baz

It calls the "bar=" method of (the object referred to by) foo, with baz
as the parameter, like this:

foo.bar=(baz)

This is a local variable assignment:

bar = baz

It simply assigns bar to be (a reference to) the same object as baz.

iTunes.PlayerPosition = 50 # call method PlayerPosition=

temp = iTunes.PlayerPosition # call method PlayerPosition
temp = 50 # assign local variable

Cheers,
Dave
 
J

Just Another Victim of the Ambient Morality

Nathan Morse said:
I had the exact same problem just a little while ago. Reading this
thread should also help.

http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/05fa7a4fe0cf2506/42096ef554d297fc

Yeah, I read that thread, too. I thought it was obvious at the time
but, here I am, confused by it, myself.
Part of what added to my confusion, which was kindly pointed out by Dave
Burt in another post on this thread, is that foo.bar = baz is invoking a
method called "bar=". Again, I come from a C/C++ background, so it really
looked like the method invocation was "bar" and it returned an object with
the method "=" defined for it.
Of course, now that I've been burned by it, I now know better and
understand that assignment is not an overrideable operator.
Thanks to everyone for the clarification...
 
R

Robert Klemme

Just said:
Part of what added to my confusion, which was kindly pointed out by Dave
Burt in another post on this thread, is that foo.bar = baz is invoking a
method called "bar=". Again, I come from a C/C++ background, so it really
looked like the method invocation was "bar" and it returned an object with
the method "=" defined for it.
Of course, now that I've been burned by it, I now know better and
understand that assignment is not an overrideable operator.
Thanks to everyone for the clarification...

Also it's important to note that Ruby's object references are different
from C++ references. In Ruby every variable (including method and block
parameters) holds a copy of the reference (like every variable was just
a C++ pointer variable and "call by value" only). So you never get into
a situation where changing a variable to point to something else has
side effects in other places of the program (e.g. the variable in the
calling scope points to another object, too).

(There are some cases that are treated specially under the hood but I
omit them on purpose because from the observed behavior there is no
difference.)

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top