def method_space(name, mod=nil, &blk)
if block_given?
name = name.to_s
raise ArgumentError if mod
mod = Module.new(&blk)
else
if Module === name
mod = name
name = mod.basename.downcase
end
mod = mod.dup
end
include mod
methods = {}
mod.instance_methods(false).each do |m|
methods[m.to_sym] = mod.instance_method(m)
mod.module_eval %{
def #{m}(*a,&b)
super(*a,&b)
end
}
end
define_method(name) do
mtab = methods
Functor.new do |op, *args|
if meth = mtab[op.to_sym]
meth.bind(self).call(*args)
else
raise NoMethodError, "undefined method `#{m}'"
end
end
end
end