Brian Candler wrote: > Somewhere deep in the innards of String#+ it is doing the equivalent of a > String.new; should it be doing a self.class.new instead? But wouldn't this be a problem if the subclass's constructor had different access/arity to that of the base class? > > Put more philosophically: is it the responsibility of a class author to > consider the requirements of possible future subclasses, in particular to > make sure that inherited methods have the 'right' behaviour in the context > of a subclass? > > If not, then the subclass will end up having to wrap those methods - i.e. > > class S > def +(arg) > S.new(super) > end > end > > That's ugly, and it seems like it was hardly worth inheriting the method > in the first place. [1] > Though perhaps ugly in code, conceptually I don't think it's too bad. The derived class ought to deal with stuff specific to the derived class, not the base class. > The 'new' method which was inherited by S (or at least gives the > appearance of being inherited) doesn't need a wrapper though: S.new > returns an S, not a String. Perhaps that's why it's surprising that the > inherited S#+ returns a String not an S. I don't really find it surprising since a sensible default (minimal) implementation of new can be implicitly defined if it's not overridden. It's never the case that you'd want a subclss's new to return a superclass (or other class) instance -- the *job* of new is to return a fresh instance of the class -- so having an implicit one is good. I'd be surprised if any method that's not "special" like this would return instances of a subclass, though. If you have some sugary way of declaring that a function implicitly "cast" it's return result to a subclass (e.g., using some keyword), I think you'd need to be able to provide some sort of copy constructor/"cast" method from base to derived class. (This could fallback to the normal constructor, but that won't always be able to handle the job.) > [1] That doesn't apply to _all_ inherited methods - e.g. the inherited > ['<=>' > is perfectly good - just methods which return String in this case