From: Pit Capitain Date: 2001-08-16T22:17:11+09:00 Subject: [ruby-talk:19893] Re: Why not?: Assigning to self On 16 Aug 2001, at 20:57, hipster wrote: > On Thu, 16 Aug 2001 17:40:48 +0900, Pit Capitain wrote: > [snip] > > Take the famous Shape class hierarchy: > > > > class Shape; ...; end > > class Rectangle < Shape; ...; end > > class Square < Rectangle; ...; end > > > > Suppose you have a Rectangle instance and use one of its resizing > > methods so that the new height equals the new width. After that it > > would be nice if the Object had become a Square instance. > > > > FYI: > > The C++ FAQ discusses an identical inheritance problem: circle > vs. ellipse -- and provides some valuable insights along the way. > > http://www.parashift.com/c++-faq-lite/proper-inheritance.html#[21.6] > > Michel Thanks for the link. It clearly shows the conflict between the intuition (a circle is a kind of an ellipse) on one side and models implemented in languages without #become on the other side. To make it clear what I was thinking of (substituting rectangle for ellipse and square for circle): class Rectangle def set_size( width, height ) if width == height become Square.new( width ) else @width, @height = width, height end end end class Square < Rectangle def set_size( width, height ) if width == height super else become Rectangle.new( width, height ) end end end This implementation meets the (at least my) intuition. Now this code should be improved so that Rectangle doesn't need to know Square, and better yet so that the "predicate subclass" (as it seems to be called in cecil), that states that a Square is a Rectangle with @width == @height, is coded only once. But I think I don't know how to do that, and since we don't have #become (yet?), all this is only theory anyway. Regards, Pit