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"