Forum: Ruby Anobject question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
A24697ab5c09da9be2d89f8789631989?d=identicon&s=25 narizona (Guest)
on 2006-05-23 22:13
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
10d4acbfdaccb4eee687a428ca00a5d8?d=identicon&s=25 Jim Weirich (weirich)
on 2006-05-23 22:30
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 Weirich
62002cee15efcf4628cd7efc19425a07?d=identicon&s=25 Tim Becker (Guest)
on 2006-05-23 22:45
(Received via mailing list)
>   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
A24697ab5c09da9be2d89f8789631989?d=identicon&s=25 narizona (Guest)
on 2006-05-23 22:58
Very nice! Thank you very much.  That helps.

Tim Becker wrote:
This topic is locked and can not be replied to.