> -----Original Message-----
> From: dave / thomases.com [mailto:dave / thomases.com]On Behalf Of Dave
> Thomas
> Sent: Friday, November 30, 2001 12:39 AM
> To: ruby-talk ML
> Subject: [ruby-talk:27028] Re: thoughts on virtual base classes,
> interfaces
> 
> [ . . . ]
> 
> Would a mixin perhaps be a better flag of this?
> 
>   class MyTask
> 
>     # We support the framework run interface
> 
>     includes Runnable
> 
>     ...
> 
>   end
> 
> 
> I don't know, as this isn't a paradigm I'm using right now. But it
> strikes me that it gives you more flexibility here, as it allows
> classes to declare their allegiance to more than one protocol.
> 
> As with inheritance, Runnable could be nothing more than an empty
> module, there for documentation only, or it could contain meaningful
> implementations, helper functions, and even defaults for the optional
> functions Phil mentions.
> 

something like this...

<SNIP>
module Runnable
  def run
    raise NotImplementedError unless @run_block
    return @run_block.call
  end
  def set_run_block(&block)
    @run_block = block
  end
end

class ATask
  def my_method_to_run
    puts "A task"
  end
end

class BTask
  include Runnable
  def run
    puts "B task"
  end
end

class CTask
  include Runnable
end

atask = ATask.new
atask.extend Runnable
atask.set_run_block {atask.my_method_to_run}

[atask, BTask.new, CTask.new].each {|task| task.run} 
#=> "A task"
#=> "B task"
#=> NotImplementedError...

</SNIP>

That way you can use the Runnable module as a tag with the
class providing its run method or make an object Runnable 
at run time through a context managed by the set_run_block...

-Rich