Trans
4/1/2008 12:27:00 AM
On Mar 31, 7:34 pm, Trans <transf...@gmail.com> wrote:
> I worked on it last night, but it's a tough nut.
Huh... it may have just a fallen into place. What do you think of:
require 'facets/module/basename'
require 'facets/module/modspace'
module Paramix # or PatrametricMixin ?
def self.append_features(base)
base.modspace.module_eval %{
def #{base.basename.to_s}(parameters, &block)
Delegator.new(#{base}, parameters, &block)
end
}
end
# It you want to define the module method by hand. You
# can use Parmix.new instead of Parmix::Delegator.new.
def self.new(delegate_module, parameters={}, &base_block)
Delegator.new(delegate_module, parameters, &base_block)
end
#
class Delegator < Module
attr :delegate_module
attr :parameters
attr :base_block
def initialize(delegate_module, parameters={}, &base_block)
@delegate_module = delegate_module
@parameters = parameters
@base_block = base_block
end
def append_features(base)
base.__send__(:include, delegate_module)
base.parametric_options[delegate_module] = parameters
base.module_eval do
define_method(:parametric_options) do
base.parametric_options
end
end
base.module_eval(&@base_block) if base_block
end
def [](name)
@parameters[name]
end
end
end
class Module
# Store for parametric mixin parameters.
#
# Returns a hash, the keys of which are the parametric mixin
module
# and the values are the parameters associacted with this module/
class.
#
# class C
# include P(:x=>1)
# end
#
# C.parametric_options[P] #=> {:x=>1}
#
def parametric_options
@parametric_options ||= {}
end
end
# Try it out
if __FILE__ == $0
module O
include Paramix
def x
parametric_options[O][:x]
end
end
# If doing it by hand instead of using include Paramix.
#def O(options)
# Paramix.new(O, options)
#end
class X
include O(:x=>1)
end
x = X.new
p x.x
p X.ancestors
end
T.