Dynamic Modules

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.

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

Trans wrote:

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.

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

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

Thanks,
T.

Daniel Schierbeck wrote:

Trans wrote:

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.

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

That should of course be `include Chewable, "foo"...'

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.

Daniel Schierbeck wrote:

Daniel Schierbeck wrote:

Trans wrote:

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.

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

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