On 5/10/05, Eric Mahurin <eric_mahurin / yahoo.com> wrote:
> --- Robert Klemme <bob.news / gmx.net> wrote:
> > Eric Mahurin wrote:
> > > Is there a way to make a class that looks like several
> > classes?
> > >  For example:
> > >
> > > class IOArray < IO
> > >     include Array # doesn't work because Array is not a
> > Module
> > >     # use IO methods calls to accomplish the Array methods
> > > end
> > >
> > > I don't need multiple inheritance.  All I want is these
> > > additional classes to appear in the ancestors list.  In the
> > > above example, IOArray could act like an IO or an Array.
> > It
> > > looks like evil.rb might have a solution, but is there a
> > > non-evil way?
> >
> > class IOArray < IO
> >   def kind_of?(cl)
> >     Array == cl || super
> >   end
> > end
> 
> Yep, that is pretty obvious.  I think that is all I need, but I
> guess overriding ancestors would complete this.
> 
> > >> x=IOArray.allocate
> > => #<IOArray:0x10184258>
> > >> x.kind_of? Array
> > => true
> >
> > But seriously, for what do you need that?  I can't think of
> > an application
> > where I would want to make something look like an Array
> > without being one.
> > Maybe it's rather Enumerable that you want?
> 
> Enumerable doesn't have random access and can't modify like
> Array (or String).  I think it would have been nice to have a
> module like "Indexable" that would cover common methods in
> Array and String.
> 
> The example I have above should probably be combining an IO and
> a String since an IO accesses characters like a String:
> 
> class IOString < IO
>     def kind_of?(c); String==c || super; end
>     # use IO methods (seek/tell/read/write) to accomplish
>     # the String methods
> end

This is generally unneeded in Ruby; If duck typing is used properly,
the ancestors and kind_of? shouldn't matter. And if it *does* matter,
then masquerading like this could cause problems:

  if obj.kind_of? String
    var.replace obj
  end

This code would break if obj is an IOString as defined above, even
though this code has no logic errors.

If you check out the StringIO class (require 'stringio'), you will
find that it inherits neither from IO nor String. But it still works
very nicely :)

cheers,
Mark