Basic Example

Require the library.

require 'paramix'

Create a parametric mixin.

module MyMixin
  include Paramix::Parametric

  parameterized do |params|

    public params[:name] do
      params[:value]
    end

  end
end

Create a class that uses the mixin and set the parameter.

class X
  include MyMixin[:name => 'f', :value=>1]
end

Then the parameter is accessible.

X.new.f.assert == 1

Nested Parematric Mixins

If we create another parametric mixin which depends on the first.

module AnotherMixin
  include Paramix::Parametric
  include MyMixin[:name => 'f', :value=>1]

  parameterized do |params|

    public params[:name] do
      params[:value]
    end

  end
end

And a class for it.

class Y
  include AnotherMixin[:name => 'g', :value=>2]
end

We can see that the parameters stay with their respective mixins.

Y.new.f.assert == 1
Y.new.g.assert == 2

However if we do the same, but do not paramterize the first module then the including module also become parametric.

module ThirdMixin
  #include Paramix::Parametric
  include MyMixin

  parameterized do |params|

    public params[:name].succ do
      params[:value]
    end

  end
end

And a class for it.

class Z
  include ThirdMixin[:name => 'q', :value=>3]
end

We can see that the value of the parameter has propogated up to its ancestor parametric module.

Z.new.q.assert == 3
Z.new.r.assert == 3

Parametric Include

Load the library.

require 'paramix'

Given a parametric mixin.

module M
  include Paramix::Parametric

  parameterized do |params|

    public :f do
      params[:p]
    end

  end
end

We can inlcude the parameteric module in a some classes.

class I1
  include M[:p => "mosh"]
end

class I2
  include M[:p => "many"]
end

And the result will vary according to the parameter set.

I1.new.f  #=> "mosh"
I2.new.f  #=> "many"

Parametric Extension

We can also extend classes witht the mixin.

class E1
  extend M[:p => "mosh2"]
end

class E2
  extend M[:p => "many2"]
end

And the results will likewise work as expected.

E1.f  #=> "mosh2"
E2.f  #=> "many2"

Dynamically Defined Methods

Parametric mixins can be used to define dynamic code.

module N
  include Paramix::Parametric

  parameterized do |params|
    attr_accessor params[:a]
  end
end

Now if we include this module we will have new attributes based on the parameter assigned.

class D1
  include N[:a => "m1"]
end

class D2
  include N[:a => "m2"]
end

d1 = D1.new
d1.m1 = :yes1

d1.m1  #=> :yes1

d2 = D2.new
d2.m2 = :yes2

d2.m2  #=> :yes2

Works with Namespaces

Parametric mixins work regardless of the namespace depth.

module R
  module M
    include Paramix::Parametric

    parameterized do |params|
      public :f do
        params[:p]
      end
    end
  end
end

module Q
  class I
    include R::M[:p => "mosh"]
  end
  class E
    extend R::M[:p => "many"]
  end
end

Q::I.new.f  #=> "mosh"

Q::E.f #=> "many"