Anobject question


#1

In prag ruby the purchased copy, the following code fragment is shown.
Look at where I added the >>>>. That line VU.new(@volume.succ). What I
think it should do is create a new object instance of the class. What
it does though is it increments the attribute @volume on an existing
object that uses the succ method.

I have verified that it does not create a new object by using
myObject.object_id. I am sure this is basic oop stuff but I do not
think I have seen it. Why does this happen like this?

I would have used an accessor to set the @volume. I am surprised by the
use of new here.

Thanks for your insight.

_Nathan

class VU
include Comparable
attr :volume
def initialize(volume) # 0…9
@volume = volume
end
def inspect
‘#’ * @volume
end

Support for ranges

def <=>(other)
self.volume <=> other.volume
end
def succ
raise(IndexError, “Volume too big”) if @volume >= 9

VU.new(@volume.succ) <<<<<
end
end


#2

narizona wrote:

In prag ruby the purchased copy, the following code fragment is shown.
Look at where I added the >>>>. That line VU.new(@volume.succ). What I
think it should do is create a new object instance of the class. What
it does though is it increments the attribute @volume on an existing
object that uses the succ method.

I have verified that it does not create a new object by using
myObject.object_id.

Try running the code like this …

v = VU.new(0)
v2 = v.succ

p v.volume, v.object_id
p v2.volume, v2.object_id

Does that do what you expect?

– Jim W.


#3

def <=>(other)
self.volume <=> other.volume
end
def succ
raise(IndexError, “Volume too big”) if @volume >= 9

VU.new(@volume.succ) <<<<<
end
end

Typically, methods like succ don’t change the state of an object,
but instead return a new object. Example:

i=1
i.succ # returns 2, but the return value is discarded…
i # i=>1 , i is still 1
x=i.succ
i # i=>1, i is STILL 1
x # x=>2 , method returned 2

Another example, if you sort an Array using sort, a new, sorted
array is returned and the original array is left unsorted.

arr = [5,4,3,2,1]
arr_sorted = arr.sort
arr_sorted # [1,2,3,4,5]
arr # [5,4,3,2,1] still unsorted

Methods that behave like this often have a counterpart that does it’s
work in place. Those method’s names end with an exclamation point:
sort!

arr = [5,4,3,2,1]
arr.sort!
arr # [1,2,3,4,5]

So for the above example, you have 2 options:

vu = VU.new(1)
vu = vu.succ

or, implement an succ! method, that changes the volume in place.


def succ!
raise(IndexError, “Volume too big”) if @volume >= 9
@volume+=1
end

Then you can just call vu.succ!

-tim


#4

Very nice! Thank you very much. That helps.

Tim B. wrote: