Dynamic Modules


#1

I would like to discuss the merits/non-merits and the best approach to
implementation of “dynamic modules” --modules that take parameters at
the time of include, thus altering their behavior per include. The
common denominator here is the altered interface of #include:

include AModule, :opt1 => :val1, :opt2 => :val2

Here’s a simple example based on the implementation I (and friends) put
together

module Mixin

 dynamic_feature do |options|

     define_method :hello do
       puts "Hello from #{options[:name]}"
     end

 end

end

class MyClass
include Mixin, :name => ‘Ruby’
end

m = MyClass.new
m.hello -> ‘Hello from Ruby’

class MyClass2
include Mixin, :name => ‘Tom’
end

m = MyClass2.new
m.hello -> ‘Hello from Tom’

T.


#2

Hi,

Why don’t you just create a factory method with the same name as your
class which creates an altered version of your base module? So your
include could be something like the following:

module MyMixin

end

def MyMixIn(option1, option2)
MyMixin # but then modified ofcourse…
end

class A
include MyMixin(option1, option2)
end

Regards,

Peter


#3

Trans wrote:

module Mixin

m = MyClass2.new
m.hello -> ‘Hello from Tom’

T.

I’d rather see this:

class Module
def include(mod, *args, &block)
mod.send :append_features, self
if mod.respond_to? :included
mod.included(self, *args, &block)
end
end
end

module Chewable
def self.included(klass, *args)
puts “Included in #{klass} with the following args:”
args.each { |arg| puts " * #{arg.inspect}" }
end
end

class Klass
include Chewable “foo”, “bar”, “baz”
end

Cheers,
Daniel


#4

Daniel S. wrote:

end
end
def include(mod, *args, &block)
args.each { |arg| puts " * #{arg.inspect}" }
end
end

class Klass
include Chewable “foo”, “bar”, “baz”
end

Cheers,
Daniel

That should of course be `include Chewable, “foo”…’


#5

Daniel S. wrote:

together

 include Mixin, :name => 'Tom'

class Module
puts “Included in #{klass} with the following args:”
Daniel

That should of course be `include Chewable, “foo”…’

Current implementation:

class Module
def include(mod, *args, &block)
mod.send :append_features, self
if mod.respond_to? :included
mod.included(self, *args, &block)
end
end
end

class Class
def is(*mods)
mods.each { |mod| include mod }
end
end

class Klass
is Chewable, Digestible
include MyModule, “foo”, “bar”, “baz”
end


#6

Also, can anyone confirm this? I heard someone say that
#append_features is being deprecated. True?

Thanks,
T.


#7

Hi Peter,

A factory method is a fair idea, but there’s a lot more to this:

MyMixin # but then modified ofcourse…

then that simple comment suggests. How do you handle that? That’s
really the heart of the matter --making a factory or overriding
#include to pass options is the easy part.

Thanks,
T.