paramix 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/{HISTORY → HISTORY.rdoc} +16 -0
- data/LICENSE +17 -668
- data/README.rdoc +25 -42
- data/Syckfile +87 -0
- data/lib/paramix.rb +81 -155
- data/meta/version +1 -1
- data/test/nested/test_nested_both.rb +26 -14
- data/test/nested/test_nested_bottom.rb +15 -11
- data/test/nested/test_nested_moot.rb +48 -0
- data/test/nested/test_nested_simple.rb +41 -0
- data/test/nested/test_nested_top.rb +19 -10
- data/test/test_paramix_callback.rb +16 -9
- data/test/test_paramix_extend.rb +7 -3
- data/test/test_paramix_include.rb +7 -3
- data/test/test_paramix_namespace.rb +11 -11
- metadata +10 -7
- data/test/test_paramix_inject.rb +0 -36
data/README.rdoc
CHANGED
@@ -1,66 +1,49 @@
|
|
1
1
|
= Paramix
|
2
2
|
|
3
|
-
* http://rubyworks.github.com/paramix
|
4
|
-
* http://
|
3
|
+
* home: http://rubyworks.github.com/paramix
|
4
|
+
* work: http://github.com/rubyworks/paramix
|
5
5
|
|
6
6
|
|
7
7
|
== DESCRIPTION
|
8
8
|
|
9
|
-
Parametric Mixins provides
|
10
|
-
|
11
|
-
|
12
|
-
== FEATURES/ISSUES
|
13
|
-
|
14
|
-
* Include mixins with class level parameterization.
|
15
|
-
* Light-weight --it does not resort to cloned anonymous modules.
|
9
|
+
Parametric Mixins provides an easy means to "functionalize" modules.
|
10
|
+
The module can then be differentiated upon usage according to the
|
11
|
+
parameters provided.
|
16
12
|
|
17
13
|
|
18
14
|
== RELEASE NOTES
|
19
15
|
|
20
|
-
Please see
|
21
|
-
|
22
|
-
|
23
|
-
== SYNOPSIS
|
24
|
-
|
25
|
-
module MyMixin
|
26
|
-
include Paramix
|
27
|
-
|
28
|
-
def hello
|
29
|
-
puts "Hello from #{mixin_parameters[MyMixin][:name]}!"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class MyClass
|
34
|
-
include MyMixin[:name => 'Ruby']
|
35
|
-
end
|
36
|
-
|
37
|
-
m = MyClass.new
|
38
|
-
m.hello #=> 'Hello from Ruby!'
|
39
|
-
|
16
|
+
Please see HISTORY.rdoc file.
|
40
17
|
|
41
|
-
== HOW TO INSTALL
|
42
18
|
|
43
|
-
|
19
|
+
== EXAMPLE
|
44
20
|
|
45
|
-
|
21
|
+
Here is a simple example that uses a a parameter
|
22
|
+
to define a method and another parameter to define
|
23
|
+
it's return value.
|
46
24
|
|
47
|
-
|
25
|
+
module M
|
26
|
+
include Paramix::Parametric
|
48
27
|
|
49
|
-
|
50
|
-
|
28
|
+
paramaterized do |params|
|
29
|
+
define_method params[:name] do
|
30
|
+
params[:value]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
51
34
|
|
52
|
-
|
53
|
-
|
54
|
-
|
35
|
+
class X
|
36
|
+
include M[:name=>'foo', :value='bar']
|
37
|
+
end
|
55
38
|
|
56
|
-
|
39
|
+
X.new.foo #=> 'bar'
|
57
40
|
|
58
41
|
|
59
|
-
==
|
42
|
+
== COPYRIGHTS
|
60
43
|
|
61
|
-
Copyright (c) 2006
|
44
|
+
Copyright (c) 2006,2010 Thomas Sawyer
|
62
45
|
|
63
|
-
This program is ditributed unser the terms of the
|
46
|
+
This program is ditributed unser the terms of the MIT license.
|
64
47
|
|
65
48
|
See LICENSE file for details.
|
66
49
|
|
data/Syckfile
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
---
|
2
|
+
announce:
|
3
|
+
service : Email
|
4
|
+
file : ~
|
5
|
+
subject : ~
|
6
|
+
mailto : ruby-talk@ruby-lang.org
|
7
|
+
active : true
|
8
|
+
|
9
|
+
grancher:
|
10
|
+
service: grancher
|
11
|
+
active: true
|
12
|
+
|
13
|
+
box:
|
14
|
+
service: Box
|
15
|
+
types : [gem, tar]
|
16
|
+
active : true
|
17
|
+
|
18
|
+
mast:
|
19
|
+
service: Mast
|
20
|
+
include: [bin, demo, lib, meta, test, "[A-Z]*"]
|
21
|
+
exclude: ~
|
22
|
+
active: true
|
23
|
+
|
24
|
+
rdoc:
|
25
|
+
service : RDoc
|
26
|
+
template : redfish
|
27
|
+
include : ~
|
28
|
+
exclude : ~
|
29
|
+
main : ~
|
30
|
+
extra : ~
|
31
|
+
active : true
|
32
|
+
|
33
|
+
ridoc:
|
34
|
+
service: RIDoc
|
35
|
+
include: ~
|
36
|
+
exclude: ~
|
37
|
+
active : true
|
38
|
+
|
39
|
+
notes:
|
40
|
+
service : DNotes
|
41
|
+
loadpath : ~
|
42
|
+
labels : ~
|
43
|
+
output : ~
|
44
|
+
format : ~
|
45
|
+
active : false
|
46
|
+
|
47
|
+
stats:
|
48
|
+
service : Stats
|
49
|
+
title : ~
|
50
|
+
loadpath : ~
|
51
|
+
exclude : ~
|
52
|
+
output : ~
|
53
|
+
active : true
|
54
|
+
|
55
|
+
testrb:
|
56
|
+
service : testrb
|
57
|
+
tests : ~
|
58
|
+
exclude : ~
|
59
|
+
loadpath : ~
|
60
|
+
requires : ~
|
61
|
+
live : false
|
62
|
+
active : true
|
63
|
+
|
64
|
+
syntax:
|
65
|
+
service : Syntax
|
66
|
+
loadpath : ~
|
67
|
+
exclude : ~
|
68
|
+
active : false
|
69
|
+
|
70
|
+
vclog:
|
71
|
+
service : VClog
|
72
|
+
format : html # xml, txt
|
73
|
+
layout : rel # gnu
|
74
|
+
typed : false
|
75
|
+
output : ~
|
76
|
+
active : false
|
77
|
+
|
78
|
+
|
79
|
+
#rubyforge:
|
80
|
+
# service : Rubyforge
|
81
|
+
# unixname: <%= project %>
|
82
|
+
# groupid : ~
|
83
|
+
# package : <%= package %>
|
84
|
+
# sitemap:
|
85
|
+
# doc/rdoc: <%= package %>
|
86
|
+
# active : false
|
87
|
+
|
data/lib/paramix.rb
CHANGED
@@ -1,190 +1,116 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
# Module parameters can be set at the time of inclusion
|
5
|
-
# or extension using Module#[] method, then parameters
|
6
|
-
# can be accessed via the #mixin_param and #mixin_parameters
|
7
|
-
# methods.
|
8
|
-
#
|
9
|
-
# module MyMixin
|
10
|
-
# include Paramix
|
11
|
-
#
|
12
|
-
# def hello
|
13
|
-
# puts "Hello from #{ mixin_param(MyMixin, :name) }!"
|
14
|
-
# end
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# class MyClass
|
18
|
-
# include MyMixin[:name => 'Ruby']
|
19
|
-
# end
|
20
|
-
#
|
21
|
-
# m = MyClass.new
|
22
|
-
# m.hello #=> 'Hello from Ruby!'
|
23
|
-
#
|
24
|
-
# You can view the full set of parameters via the +mixin_parameters+ method.
|
25
|
-
#
|
26
|
-
# MyClass.mixin_parameters #=> {MyMixin => {:name => 'ruby'}}
|
27
|
-
#
|
28
|
-
# Including Paramix into a module is essentially equivalent to defining
|
29
|
-
# a module method:
|
30
|
-
#
|
31
|
-
# def [](parameters)
|
32
|
-
# Paramix::Proxy.new(self, parameters)
|
33
|
-
# end
|
34
|
-
#
|
35
|
-
# Paramix::Proxy.new can also take a block that injects code into the
|
36
|
-
# mixin. This is useful as an alternative to using the #included
|
37
|
-
# callback for creating metaclass dynamics based on mixin parameters.
|
38
|
-
# For example:
|
39
|
-
#
|
40
|
-
# module MyMixin
|
41
|
-
# def self.[](parameters)
|
42
|
-
# Paramix::Mixin.new(self, parameters) do
|
43
|
-
# attr_accessor parameters[MyMixin][:name]
|
44
|
-
# end
|
45
|
-
# end
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# As opposed to:
|
49
|
-
#
|
50
|
-
# module MyMixin
|
51
|
-
# include Paramix
|
52
|
-
#
|
53
|
-
# def self.included(base)
|
54
|
-
# base.class_eval do
|
55
|
-
# attr_accessor base.mixin_parameters[:name]
|
56
|
-
# end
|
57
|
-
# super(base)
|
58
|
-
# end
|
59
|
-
# end
|
1
|
+
# paramix.rb, Copyright (c)2010 Thomas Sawyer [MIT License]
|
2
|
+
|
3
|
+
# Paramix project namespace.
|
60
4
|
#
|
61
5
|
module Paramix
|
62
6
|
|
7
|
+
# = Parametric
|
63
8
|
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
9
|
+
# Parametric mixins provides parameters for mixin modules.
|
10
|
+
# Module parameters can be set at the time of inclusion
|
11
|
+
# or extension using Module#[] method, then parameters
|
12
|
+
# can be accessed via the #mixin_parameters method.
|
69
13
|
#
|
70
|
-
module
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
14
|
+
# module MyMixin
|
15
|
+
# include Paramix::Parametric
|
16
|
+
#
|
17
|
+
# parameterized |params|
|
18
|
+
# define_method :hello do
|
19
|
+
# puts "Hello from #{params[:name]}!"
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# class MyClass
|
25
|
+
# include MyMixin[:name => 'Ruby']
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# MyClass.new.hello #=> 'Hello from Ruby!'
|
29
|
+
#
|
30
|
+
#
|
31
|
+
module Parametric
|
85
32
|
|
86
33
|
#
|
87
|
-
def
|
88
|
-
|
89
|
-
@parameters = parameters || {}
|
90
|
-
@block = block
|
34
|
+
def self.included(base)
|
35
|
+
base.extend(Extensions)
|
91
36
|
end
|
92
37
|
|
93
38
|
#
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
39
|
+
module Extensions
|
40
|
+
#
|
41
|
+
def [](parameters={})
|
42
|
+
Mixin.new(self, parameters)
|
43
|
+
end
|
99
44
|
|
100
|
-
|
45
|
+
#
|
46
|
+
def parameterized(&code)
|
47
|
+
@code ||= []
|
48
|
+
if block_given?
|
49
|
+
@code << code
|
50
|
+
else
|
51
|
+
@code
|
52
|
+
end
|
53
|
+
end
|
101
54
|
|
102
|
-
base
|
103
|
-
|
55
|
+
def append_features(base)
|
56
|
+
return super(base) if Mixin === base || Mixin === self
|
104
57
|
|
105
|
-
|
58
|
+
base.extend(Extensions)
|
106
59
|
|
107
|
-
|
108
|
-
|
60
|
+
anc = ancestors.find{ |a| a.respond_to?(:parameterized) }
|
61
|
+
base.parameterized.concat(anc.parameterized)
|
109
62
|
|
110
|
-
|
111
|
-
|
112
|
-
mixin = @mixin
|
63
|
+
super(base)
|
64
|
+
end
|
113
65
|
|
114
|
-
|
66
|
+
#
|
67
|
+
def extend_object(base)
|
68
|
+
return super(base) if Mixin === base || Mixin === self
|
115
69
|
|
116
|
-
|
117
|
-
metabase.mixin_parameters[mixin].update(@parameters)
|
70
|
+
base.extend(Extensions)
|
118
71
|
|
119
|
-
|
72
|
+
anc = ancestors.find{ |a| a.respond_to?(:parameterized) }
|
73
|
+
base.parameterized.concat(anc.parameterized)
|
120
74
|
|
121
|
-
|
75
|
+
super(base)
|
76
|
+
end
|
122
77
|
|
123
|
-
metabase.module_eval(&@block) if @block
|
124
78
|
end
|
125
79
|
|
80
|
+
# An instance of the Mixin module class is what is porduced
|
81
|
+
# when parameters are applied to a parametric module.
|
126
82
|
#
|
127
|
-
|
128
|
-
|
129
|
-
def
|
130
|
-
|
131
|
-
self
|
132
|
-
|
133
|
-
|
134
|
-
q = a.mixin_parameters
|
135
|
-
#if q = Paramix.mixin_params[a]
|
136
|
-
if q[m] && q[m].key?(n)
|
137
|
-
r = q[m][n]
|
138
|
-
else
|
139
|
-
q.each do |k,v|
|
140
|
-
h.update(v)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
#end
|
83
|
+
class Mixin < Module
|
84
|
+
|
85
|
+
def initialize(base, parameters)
|
86
|
+
include(base)
|
87
|
+
#base.append_features(self)
|
88
|
+
base.parameterized.each do |code|
|
89
|
+
instance_exec(parameters, &code)
|
144
90
|
end
|
145
|
-
|
91
|
+
#base.parameterized.clear
|
146
92
|
end
|
147
|
-
end
|
148
93
|
|
149
|
-
#
|
150
|
-
module ClassParameterize
|
151
94
|
#
|
152
|
-
def
|
153
|
-
|
154
|
-
|
155
|
-
break if Paramix==a
|
156
|
-
if q = a.meta_class.mixin_parameters #[class << a; self ; end]
|
157
|
-
#if q = Paramix.mixin_params[class << a; self ; end]
|
158
|
-
if q[m] && q[m].key?(n)
|
159
|
-
r = q[m][n]
|
160
|
-
else
|
161
|
-
q.each do |k,v|
|
162
|
-
h.update(v)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
r ? r : h[n]
|
95
|
+
def public(name, &code)
|
96
|
+
define_method(name, &code)
|
97
|
+
super(name)
|
168
98
|
end
|
169
|
-
end
|
170
99
|
|
171
|
-
|
100
|
+
#
|
101
|
+
def private(name, &code)
|
102
|
+
define_method(name, &code)
|
103
|
+
super(name)
|
104
|
+
end
|
172
105
|
|
173
|
-
|
106
|
+
#
|
107
|
+
def protected(name, &code)
|
108
|
+
define_method(name, &code)
|
109
|
+
super(name)
|
110
|
+
end
|
174
111
|
|
175
|
-
|
176
|
-
class Module
|
112
|
+
end
|
177
113
|
|
178
|
-
def mixin_parameters
|
179
|
-
@mixin_params ||= {}
|
180
114
|
end
|
181
115
|
|
182
|
-
alias_method :mixin_params, :mixin_parameters
|
183
|
-
|
184
|
-
end
|
185
|
-
|
186
|
-
module Kernel
|
187
|
-
def meta_class
|
188
|
-
(class << self; self; end)
|
189
|
-
end
|
190
116
|
end
|