From: r2d2@... (Niklas Frykholm) Date: 2002-01-28T01:14:19+09:00 Subject: Re: Subrange of String subclass => invalid object [Yukihiro Matsumoto]: >|Sorry, I'm having a hard time accepting that it's okay for operations to >|produce broken objects. > > Don't feel sorry. I agree it's sloppy. Maybe I didn't think enough > deep when I accepted this RCR. Let's discuss for "better way". I agree that it is bad to get broken objects, but I'm also not so thrilled about behavior like this: class Foo < String end Foo.new('a').next.type # => String f = Foo.new('a') f.next! f.type # => Foo This is a less serious, but on the other hand much more frequent problem. For example, I don't know how many times I have created array classes such as ArrayOfSprites < Array with some extra convenience methods. Overriding all the methods in Array each time is quite gruesome. Possible ways forward: (a) "Require" that every object has a working #dup method. I.e., if standard #dup doesn't work the class should implement its own #dup. If #dup produceds a broken object then _that_ is considered the problem. To return an object of the subclass, use #dup to create instances of the subclass and call the bang-methods on those instances. (Methods which don't have bang-correspondences always return the superclass.) (b) Let all methods return objects of the superclass and provide a convenience mixin for those who wants to create subclasses that return objects of the subclass. In the example above, the mixin could be module StringExtension def next type.new(super.next) end # ... end class Foo < String include StringExtension #... end Convenience mixins should be provided for String, Array and Hash. // Niklas