On Fri, Nov 30, 2001 at 07:15:25AM +0900, Phil Tomson wrote:
> 
> I want to pass around objects of a type which respond to a method called 
> 'run'.  Optionally, they might respond to a few other methods, let's call 
> them get_serverTimeout and get_clientTimeout - but these last two are 
> optoinal, I'll test for them with 'respond_to'.
> 
> So I got to thinking that perhaps I could make something like a virtual 
> base class where you raise an exception if 'run' isn't defined in the 
> inheriting class.  But then I thought, "why bother" - Ruby is dynamic, any 
> object which responds to 'run' is going to work.  So perhaps the best way 
> of communicating this to users of the framework (a task distributor which 
> distrubutes tasks to different clients).  So it seems that 
> philosophically, the best way to do it is just to document the required 
> (and optoinal interface) for the classes of objects to be distributed.
> 
> Any thoughts? How are others handling these types of issues?
> 
> Phil

You can, of course, use respond_to? to determine if run() is
implemented, and raise an exception if it is not.

One thing I like to do (which is probably overkill for what you are
doing) is to force the user to implement the method:

  module Fooable
    mixin_requires :foo
    def bar
      foo
    end
  end

  class Foo
    include Fooable #=> RuntimeError: Module Foo does not defined method foo
    def foo
      puts "foo!"
    end
    include Fooable #=> okay
  end

This has the disadvantage that the include lines must be the last
statement in the class definition, but I'm willing to live with that.
You can see my implmentation of mixin_requires at:

  http://rm-f.net/~cout/ruby/treasures/RubyTreasures-0.1/lib/hacks/safe_mixin.rb.html

You still, of course, have to check at run-time to make sure that the
passed-in object is a Foobable object, but at least this way if you add
new requirements to the interface, you get informed early that you've
made a mistake (at load time instead of run time).

It should be trivial to modify a documentation generator to grep for the
mixin_requires line and automatically document the requirement.

Paul