Delayed evaluation of append_features

Hi,

I was just reading this bit:

http://judofyr.net/posts/never-gonna-let-you-go.html

And that had me wondering about my "interface" implementation. At the
moment, users must declare the methods before they implement the
interface. However, now I'm wondering if I could somehow delay the
evaluation of append_features until *after* methods have been
declared.

Could continuations be used for this? Below is the code and a sample
at the end.

# A module for implementing Java style interfaces in Ruby. For more
information
# about Java interfaces, please see:

···

#
# http://java.sun.com/docs/books/tutorial/java/concepts/interface.html
#
module Interface
  # The version of the interface library.
  Interface::VERSION = '1.1.0a'

  # Raised if a class or instance does not meet the interface
requirements.
  class MethodMissing < RuntimeError; end

  alias :extends :extend

  private

  def extend_object(obj)
    return append_features(obj) if Interface === obj
    append_features(class << obj; self end)
    included(obj)
  end

  def append_features(mod)
    return super if Interface === mod

    # Is this a sub-interface?
    inherited = (self.ancestors-[self]).select{ |x| Interface === x }
    inherited = inherited.map{ |x| x.instance_variable_get('@ids') }

    # Store required method ids
    ids = @ids + inherited.flatten
    @unreq ||= []

    # Iterate over the methods, minus the unrequired methods, and
raise
    # an error if the method has not been defined.
    (ids - @unreq).uniq.each do |id|
      id = id.to_s if RUBY_VERSION.to_f < 1.9
      unless mod.instance_methods(true).include?(id)
        raise Interface::MethodMissing, id
      end
    end

    super mod
  end

  public

  # Accepts an array of method names that define the interface. When
this
  # module is included/implemented, those method names must have
already been
  # defined.
  #
  def required_methods(*ids)
    @ids = ids
  end

  alias requires required_methods

  # Accepts an array of method names that are removed as a requirement
for
  # implementation. Presumably you would use this in a sub-interface
where
  # you only wanted a partial implementation of an existing interface.
  #
  def unrequired_methods(*ids)
    @unreq ||= []
    @unreq += ids
  end
end

class Object
  # The interface method creates an interface module which typically
sets
  # a list of methods that must be defined in the including class or
module.
  # If the methods are not defined, an Interface::MethodMissing error
is raised.
  #
  # A interface can extend an existing interface as well. These are
called
  # sub-interfaces, and they can included the rules for their parent
interface
  # by simply extending it.
  #
  # Example:
  #
  # # Require 'alpha' and 'beta' methods
  # AlphaInterface = interface{
  # required_methods :alpha, :beta
  # }
  #
  # # A sub-interface that requires 'beta' and 'gamma' only
  # GammaInterface = interface{
  # extends AlphaInterface
  # required_methods :gamma
  # unrequired_methods :alpha
  # }
  #
  # # Raises an Interface::MethodMissing error because :beta is not
defined.
  # class MyClass
  # def alpha
  # # ...
  # end
  # implements AlphaInterface
  # end
  #
  def interface(&block)
    mod = Module.new
    mod.extend(Interface)
    mod.instance_eval(&block)
    mod
  end
end

class Module
  alias :implements :include
end

FooInterface = interface{
  requires :alpha, :beta
}

# How it works now
class Foo
  def alpha;end
  def beta;end
  implements FooInterface
end

# How I want it to work
class Foo
  implements FooInterface
  def alpha;end
  def beta;end
end

Regards,

Dan