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:

What Is an Interface? (The Java™ Tutorials > Learning the Java Language > Object-Oriented Programming Concepts)

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