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