From: Geoff Youngs Date: 2003-11-19T18:39:09+09:00 Subject: Re: "stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types) ) On Wed, Nov 19, 2003 at 11:00:43AM +0900, Christoph wrote: > Geoff Youngs wrote: > .. > > So, for the above example, using Interface::Enumerable could > > allow an array class to use the brute force Enumerable#max, > > but wouldn't prevent the Range class from implementing a much > > simpler and faster Range#max. > Whats the improvement here. We can already fine tune > included method for each ``includy'' > class Range > def max > unless exclude_end? > self.end if self.begin <= self.end > else > # the super refers to Enumerable#max > super if self.begin <= self.end > end > end > end > but maybe I missunderstood something(s)? It wasn't a particularly good example (but just checking the code, a good example wouldn't have worked properly anyway :( - line 87 has a bug). But the purpose was to mainly to add consistency to the following: class Foo def bar puts "Foo#bar" end end class Bar < Foo end module Iface def bar puts "Iface#bar" end end If Foo has Iface mixed in, then Bar#bar will call Foo#bar, but if Bar has Iface mixed in (and Foo doesn't already), then Bar#bar maps to Iface#bar. The purpose was to provide a more consistent way of not overriding existing methods when including a module which defines methods of the same name as existing class methods, by ensuring that optional methods are only ever used if the class doesn't have a method of that name defined *or* inherited. The other advantage was introspection: Interface.needs returns a list of required methods, Interface.class_needs returns a list of required singleton methods and Interface.optional returns a list of methods which the Interface can provide unless the class has it's own implementation. TTFN, Geoff.