mixin 0.4.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/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2008 Christian Herschel Stevenson, Persapient Systems
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,6 @@
1
+ Mixin by Hersch Stevenson (xain)
2
+
3
+ http://persapient.com/mixin (comming soon)
4
+
5
+
6
+ This must be an early beta version.
@@ -0,0 +1,8 @@
1
+ require 'mixin'
2
+
3
+
4
+ module Metable
5
+ include Metable::InstanceMethods
6
+ extend_class_mixin Metable::ClassMethods
7
+ extend_module_mixin Metable::ClassMethods
8
+ end
@@ -0,0 +1,77 @@
1
+ require 'metable/instance_methods'
2
+
3
+
4
+ module Metable
5
+ module ClassMethods
6
+ include InstanceMethods
7
+
8
+ # Returns +true+ if the named class method is defined by the invoking class
9
+ # (or its extended modules or ancestors). Public and protected (yes,
10
+ # _protected_) class methods are matched.
11
+ def class_method_defined?(method_name)
12
+ eigenclass.method_defined? method_name
13
+ end
14
+
15
+ # Returns +true+ if the named public class method is defined by the invoking
16
+ # class (or its extended modules or ancestors).
17
+ def public_class_method_defined?(method_name)
18
+ eigenclass.public_method_defined? method_name
19
+ end
20
+
21
+ # Returns +true+ if the named protected class method is defined by the invoking
22
+ # class (or its extended modules or ancestors).
23
+ def protected_class_method_defined?(method_name)
24
+ eigenclass.protected_method_defined? method_name
25
+ end
26
+
27
+ # Returns +true+ if the named private class method is defined by the invoking
28
+ # class (or its extended modules or ancestors).
29
+ def private_class_method_defined?(method_name)
30
+ eigenclass.private_method_defined? method_name
31
+ end
32
+
33
+
34
+ alias protected_class_method protected_singleton_method
35
+
36
+
37
+ private
38
+
39
+ alias alias_class_method alias_singleton_method
40
+
41
+ alias define_class_method define_singleton_method
42
+ alias define_public_class_method define_singleton_method
43
+ alias define_protected_class_method define_protected_singleton_method
44
+ alias define_private_class_method define_private_singleton_method
45
+
46
+
47
+ # Defines an instance method for _name_ which becomes an enclosure around
48
+ # a given object. The enclosed object is the result of the given block,
49
+ # which is evaluated within the context of the invoking instance object
50
+ # using +instance_eval+ at the time in which the enclosure method is first
51
+ # invoked on that instance. The _access_ argument can be a symbol or string
52
+ # representing the access level for the enclosure method (public, private,
53
+ # or protected). The default access level is +private+.
54
+ def enclosed_attr(name, access = :private, &block) # :doc:
55
+ define_method name do
56
+ ea = instance_eval &block
57
+ eigen_eval { define_method(name) { ea } && __send__(access, name) }
58
+ ea
59
+ end
60
+ __send__ access, name
61
+ end
62
+
63
+
64
+ def public_enclosure(*names, &block) # :doc:
65
+ names.each { |name| enclosed_attr name, :public, &block }
66
+ end
67
+
68
+ def private_enclosure(*names, &block) # :doc:
69
+ names.each { |name| enclosed_attr name, :private, &block }
70
+ end
71
+
72
+ def protected_enclosure(*names, &block) # :doc:
73
+ names.each { |name| enclosed_attr name, :protected, &block }
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,93 @@
1
+ module Metable
2
+ module InstanceMethods
3
+
4
+ # Returns the invoking object's eigenclass.
5
+ def eigenclass
6
+ class << self
7
+ self
8
+ end
9
+ end
10
+
11
+ alias metaclass eigenclass
12
+
13
+
14
+ # Evaluates a string containing Ruby source code, or the given block within
15
+ # the context of the invoking object's eigenclass.
16
+ #
17
+ # <tt>_obj_.eigen_eval { _block_ }</tt> would be equivalent to
18
+ # <tt>_obj_.eigenclass.instance_eval { _block_ }</tt>
19
+ #
20
+ # :call-seq:
21
+ # eigen_eval(<em>string</em> <, <em>file</em> <, <em>line</em>>>) -> <em>other_obj</em>
22
+ # eigen_eval { <em>block</em> } -> <em>other_obj</em>
23
+ #
24
+ def eigen_eval(*args, &block)
25
+ eigenclass.instance_eval(*args, &block)
26
+ end
27
+
28
+
29
+ # Makes the invoking object's existing singleton methods private.
30
+ def private_singleton_method(*method_ids)
31
+ eigen_eval { private *method_ids }
32
+ end
33
+
34
+ # Makes the invoking object's existing singleton methods protected.
35
+ def protected_singleton_method(*method_ids)
36
+ eigen_eval { protected *method_ids }
37
+ end
38
+
39
+ # Makes the invoking object's existing singleton methods public.
40
+ def public_singleton_method(*method_ids)
41
+ eigen_eval { public *method_ids }
42
+ end
43
+
44
+
45
+ private
46
+
47
+ # Makes _new_id_ an alias of the singleton method _old_id_ within the
48
+ # invoking object.
49
+ def alias_singleton_method(new_id, old_id) # :doc:
50
+ eigen_eval { alias_method new_id, old_id }
51
+ end
52
+
53
+ # Defines a public singleton method on the invoking object (similar to
54
+ # +define_method+).
55
+ #
56
+ # <em>Aliased as</em> +define_public_singleton_method+
57
+ #
58
+ # :call-seq:
59
+ # define_singleton_method(<em>symbol</em>, <em>method</em>) -> <em>method</em>
60
+ # define_singleton_method(<em>symbol</em>) { <em>block</em> } -> <em>proc</em>
61
+ #
62
+ def define_singleton_method(*args, &block) # :doc:
63
+ eigen_eval { define_method(*args, &block) }
64
+ end
65
+
66
+ alias define_public_singleton_method define_singleton_method # :doc:
67
+
68
+ # Defines a private singleton method on the invoking object (similar to
69
+ # +define_method+).
70
+ #
71
+ # :call-seq:
72
+ # define_private_singleton_method(<em>symbol</em>, <em>method</em>) -> <em>method</em>
73
+ # define_private_singleton_method(<em>symbol</em>) { <em>block</em> } -> <em>proc</em>
74
+ #
75
+ def define_private_singleton_method(*args, &block) # :doc:
76
+ define_singleton_method(*args, &block)
77
+ private_singleton_method(args.first)
78
+ end
79
+
80
+ # Defines a protected singleton method on the invoking object (similar to
81
+ # +define_method+).
82
+ #
83
+ # :call-seq:
84
+ # define_protected_singleton_method(<em>symbol</em>, <em>method</em>) -> <em>method</em>
85
+ # define_protected_singleton_method(<em>symbol</em>) { <em>block</em> } -> <em>proc</em>
86
+ #
87
+ def define_protected_singleton_method(*args, &block) # :doc:
88
+ define_singleton_method(*args, &block)
89
+ protected_singleton_method(args.first)
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,152 @@
1
+ require 'metable/class_methods'
2
+
3
+
4
+ # Mixin is an extension to +Module+ that is intended to ease the development
5
+ # of mixins that involve both class and instance methods.
6
+ #
7
+ module Mixin
8
+ include Metable::InstanceMethods
9
+ extend Metable::ClassMethods
10
+
11
+ class ModuleMixin < Module # :nodoc:
12
+ include Metable::InstanceMethods
13
+
14
+ def initialize(mixin)
15
+ define_private_singleton_method(:mixin) { mixin }
16
+ super()
17
+ end
18
+
19
+ def module_eval(*args, &block)
20
+ mixin.eigenclass.module_eval *args, &block
21
+ super
22
+ end
23
+
24
+ alias class_eval module_eval
25
+ end
26
+
27
+
28
+ enclosed_attr(:__class_mixin__) { Module.new }
29
+ enclosed_attr(:__module_mixin__) { ModuleMixin.new(self) }
30
+
31
+
32
+ # Extends the given modules to the classes that subsequently include the
33
+ # invoking module or one of its submodules.
34
+ #
35
+ # Calling <tt>SomeMixin.extend_class_mixin(SomeClassMethods)</tt>
36
+ # would be equivalent to:
37
+ #
38
+ # module SomeMixin
39
+ # class_mixin do
40
+ # include SomeClassMethods
41
+ # end
42
+ # end
43
+ #
44
+ def extend_class_mixin(*modules)
45
+ class_mixin { include *modules }
46
+ end
47
+
48
+
49
+ # Works like +extend_class_mixin+ except that the given modules are instead
50
+ # extended to the invoking module and the modules that subsequently include
51
+ # it rather than their including classes.
52
+ def extend_module_mixin(*modules)
53
+ module_mixin { include *modules }
54
+ end
55
+
56
+
57
+ private
58
+
59
+ # Returns the invoking modules's +class_mixin+ module object. When a block is
60
+ # passed, it is evaluated in the context of the +class_mixin+ module.
61
+ #
62
+ # Given the module M, M's +class_mixin+ module is included by the +class_mixin+
63
+ # module of any module that includes M and is extended to any class that
64
+ # includes M.
65
+ #
66
+ # module Active
67
+ # class_mixin do
68
+ # def active?; true; end
69
+ # end
70
+ # end
71
+ #
72
+ # module Hyper
73
+ # include Active
74
+ # class_mixin do
75
+ # def hyper?; true; end
76
+ # end
77
+ # end
78
+ #
79
+ # class HyperClass
80
+ # include Hyper
81
+ # end
82
+ #
83
+ # HyperClass.active? -> true
84
+ # HyperClass.hyper? -> true
85
+ #
86
+ # :call-seq:
87
+ # class_mixin { <em>block</em> } -> <em>module</em>
88
+ # class_mixin -> <em>module</em>
89
+ #
90
+ def class_mixin(&block) # :doc:
91
+ __class_mixin__.module_eval(&block) if block_given?
92
+ __class_mixin__
93
+ end
94
+
95
+
96
+ # Works the same as +class_mixin+ except that the invoking module's
97
+ # +module_mixin+ is instead extended to the invoking module its self rather
98
+ # than its including classes.
99
+ #
100
+ # module Active
101
+ # module_mixin do
102
+ # def active_mixin?; true; end
103
+ # end
104
+ # end
105
+ #
106
+ # module Hyper
107
+ # include Active
108
+ # end
109
+ #
110
+ # class ActiveClass
111
+ # include Active
112
+ # end
113
+ #
114
+ # Active.active_mixin? -> true
115
+ # Hyper.active_mixin? -> true
116
+ # ActiveClass.respond_to?(:active_mixin?) -> false
117
+ #
118
+ # :call-seq:
119
+ # module_mixin { <em>block</em> } -> <em>module</em>
120
+ # module_mixin -> <em>module</em>
121
+ #
122
+ def module_mixin(&block) # :doc:
123
+ __module_mixin__.module_eval(&block) if block_given?
124
+ __module_mixin__
125
+ end
126
+
127
+ # Call the DRY Police! ;)
128
+
129
+
130
+ def included(submodule)
131
+ if submodule.kind_of? Class
132
+ submodule.extend __class_mixin__
133
+ else
134
+ submodule.extend_module_mixin __module_mixin__
135
+ submodule.extend_class_mixin __class_mixin__
136
+ end
137
+ super
138
+ end
139
+
140
+ end
141
+
142
+
143
+
144
+ [:module_mixin, :extend_module_mixin, :class_mixin, :extend_class_mixin].each do |name|
145
+ Module.class_eval %Q{
146
+ def #{name}(*args, &block)
147
+ extend ::Mixin
148
+ send :#{name}, *args, &block
149
+ end
150
+ }
151
+ end
152
+ Module.class_eval { private :module_mixin, :class_mixin }
@@ -0,0 +1,220 @@
1
+ $:.unshift "#{File.dirname(__FILE__)}/../lib"
2
+ $:.unshift "#{File.dirname(__FILE__)}/test_subjects"
3
+
4
+ require 'mixin'
5
+ require 'test/unit'
6
+
7
+
8
+ class MixinTest < Test::Unit::TestCase
9
+
10
+
11
+ def meeper_mxns
12
+ [Meeper, ActiveMeeper, HyperMeeper]
13
+ end
14
+
15
+ def meeper_clss
16
+ [MeeperCls, ActiveMeeperCls, HyperMeeperCls]
17
+ end
18
+
19
+
20
+ def assert_no_response(obj, msg, message = nil)
21
+ assert !obj.respond_to?(msg), message
22
+ end
23
+
24
+
25
+ def test_respond_to
26
+ load 'meepers.rb'
27
+
28
+ [:meeper_mixin?, :meep].each do |meth|
29
+ meeper_mxns.each { |mxn| assert_respond_to mxn, meth }
30
+ meeper_clss.each { |cls| assert_no_response cls, meth }
31
+ end
32
+ [:meeper_class?, :says].each do |meth|
33
+ meeper_mxns.each { |mxn| assert_no_response mxn, meth }
34
+ meeper_clss.each { |cls| assert_respond_to cls, meth }
35
+ end
36
+
37
+ meeper_mxns[1..-1].each do |mxn|
38
+ assert_respond_to mxn, :active?
39
+ assert_no_response mxn, :active_meeper?
40
+ end
41
+ meeper_clss[1..-1].each do |cls|
42
+ assert_no_response cls, :active?
43
+ assert_respond_to cls, :active_meeper?
44
+ end
45
+ assert_no_response Meeper, :active
46
+ assert_no_response MeeperCls, :active_meeper?
47
+
48
+ assert_respond_to HyperMeeper, :hyperactive?
49
+ assert_no_response HyperMeeperCls, :hyperactive?
50
+ assert_respond_to HyperMeeperCls, :hyper_meeper?
51
+ assert_no_response HyperMeeper, :hyper_meeper?
52
+ meeper_mxns[0..-2].each { |mxn| assert_no_response mxn, :hyperactive? }
53
+ meeper_clss[0..-2].each { |cls| assert_no_response cls, :hyper_meeper? }
54
+ end
55
+
56
+
57
+ def test_scope
58
+ load 'scopers.rb'
59
+
60
+ assert M.class_variables.empty?
61
+ assert M.instance_variables.empty?
62
+
63
+ [M::Scoper, M::XScoper, M::ScoperCls, M::XScoperCls].each do |mod|
64
+ assert_same mod, mod.me
65
+ assert_same :cls, mod.cls_attr
66
+ end
67
+ assert_same :inst, M::Scoper.inst_attr
68
+ [M::XScoper, M::ScoperCls].each { |mod| assert_nil mod.inst_attr }
69
+ assert_same :xinst, M::XScoperCls.inst_attr
70
+ M::XScoper.instance_variable_set :@inst_attr, :woot
71
+ assert_same :woot, M::XScoper.inst_attr
72
+ end
73
+
74
+
75
+ def test_hopons
76
+ load 'meepers.rb'
77
+ load 'hopons.rb'
78
+
79
+ Meeper.module_eval do
80
+ module_mixin do
81
+ def newb
82
+ :newbie
83
+ end
84
+ end
85
+ class_mixin do
86
+ def noob
87
+ :nooby
88
+ end
89
+ end
90
+ end
91
+
92
+ meeper_mxns.each { |mxn| assert_respond_to mxn, :newb }
93
+ meeper_clss.each { |cls| assert_respond_to cls, :noob }
94
+
95
+ Meeper.module_eval do
96
+ include Duck
97
+ module_mixin do
98
+ include Plain
99
+ end
100
+ class_mixin do
101
+ include Plain
102
+ end
103
+ end
104
+
105
+ assert_respond_to Meeper, :quack
106
+ assert_respond_to Meeper, :flavor
107
+ (meeper_mxns[1..-1] + meeper_clss).each do |mod|
108
+ assert_no_response mod, :quack
109
+ assert_no_response mod, :flavor
110
+ end
111
+ end
112
+
113
+
114
+ def test_extenders
115
+ load 'extenders.rb'
116
+ load 'hopons.rb'
117
+
118
+ assert_same :module, Xtendr.nudge
119
+ assert_same :module, Xtendrer.nudge
120
+ assert_same :class, Xtended.nudge
121
+ assert_same :class, Xtendedr.nudge
122
+ assert_same :mod_mxn_ping, Xtendr.ping
123
+ assert_same :mod_mxn_ping, Xtendrer.ping
124
+ assert_same :cls_mxn_ping, Xtended.ping
125
+ assert_same :cls_mxn_ping, Xtendedr.ping
126
+
127
+ Xtendr.extend_module_mixin Plain
128
+ Xtendr.extend_class_mixin Plain
129
+
130
+ assert_same :vanilla, Xtendr.flavor
131
+ assert_no_response Xtendrer, :flavor
132
+ assert_no_response Xtended, :flavor
133
+
134
+ xhaustv = Module.new { include Xtendr }
135
+ xhausted = Class.new { include Xtendr }
136
+ assert_same :vanilla, xhaustv.flavor
137
+ assert_same :vanilla, xhausted.flavor
138
+ end
139
+
140
+
141
+ def test_includers
142
+ load 'includers.rb'
143
+ load 'hopons.rb'
144
+
145
+ assert_same :module, Includr.nudge
146
+ assert_same :module, Includrer.nudge
147
+ assert_same :class, Included.nudge
148
+ assert_same :class, Includedr.nudge
149
+ assert_same :mod_mxn_ping, Includr.ping
150
+ assert_same :mod_mxn_ping, Includrer.ping
151
+ assert_same :cls_mxn_ping, Included.ping
152
+ assert_same :cls_mxn_ping, Includedr.ping
153
+
154
+ Includr.module_eval do
155
+ module_mixin { include Plain }
156
+ end
157
+ Includr.module_eval do
158
+ class_mixin { include Plain }
159
+ end
160
+
161
+ assert_same :vanilla, Includr.flavor
162
+ assert_no_response Includrer, :flavor
163
+ assert_no_response Included, :flavor
164
+
165
+ xhaustv = Module.new { include Includr }
166
+ xhausted = Class.new { include Includr }
167
+ assert_same :vanilla, xhaustv.flavor
168
+ assert_same :vanilla, xhausted.flavor
169
+ end
170
+
171
+
172
+ def test_supers
173
+ load 'soopers.rb'
174
+
175
+ assert_equal [0,1], Soopr1.giv_er
176
+ assert_equal [0,1,2], Soopr2.giv_er
177
+ assert_equal [0,1,2,3], Soopr3.giv_er
178
+
179
+ assert_equal [1,0], SooprC1.giv_em
180
+ assert_equal [2,1,0], SooprC2.giv_em
181
+ assert_equal [3,2,1,0], SooprC3.giv_em
182
+
183
+ assert_equal [0,1,2,3,7,9], Soopr4.giv_er
184
+ assert_equal [666,9,7,3,2,1,0], SooprC4.giv_em
185
+ end
186
+
187
+
188
+ def test_laziness
189
+ load 'sleepers.rb'
190
+
191
+ [LazyModExt, LazyClsExt, LazyModMxn, LazyClsMxn].each do |mxn|
192
+ assert_kind_of Mixin, mxn
193
+ end
194
+ assert SansMxn.private_methods.include?('module_mixin')
195
+ assert SansMxn.private_methods.include?('class_mixin')
196
+ assert !SansMxn.kind_of?(Mixin)
197
+ SansMxn.extend_class_mixin Module.new
198
+ assert_kind_of Mixin, SansMxn
199
+ end
200
+
201
+
202
+ def test_module_mixin_module_eval
203
+ load 'meepers.rb'
204
+
205
+ Meeper.module_eval do
206
+ module_mixin.module_eval do
207
+ def rico?
208
+ true
209
+ end
210
+ end
211
+ module_mixin.class_eval %Q{
212
+ def suave?
213
+ true
214
+ end
215
+ }
216
+ end
217
+ assert Meeper.rico? && Meeper.suave?
218
+ end
219
+
220
+ end
@@ -0,0 +1,33 @@
1
+ require 'nudgers'
2
+
3
+
4
+ module Xtendr
5
+ extend_module_mixin ModNudgr
6
+ extend_class_mixin ClsNudgr
7
+
8
+ module_mixin do
9
+ def ping
10
+ :mod_mxn_ping
11
+ end
12
+ end
13
+
14
+ class_mixin do
15
+ def ping
16
+ :cls_mxn_ping
17
+ end
18
+ end
19
+ end
20
+
21
+
22
+ module Xtendrer
23
+ include Xtendr
24
+ end
25
+
26
+
27
+ class Xtended
28
+ include Xtendr
29
+ end
30
+
31
+ class Xtendedr
32
+ include Xtendrer
33
+ end
@@ -0,0 +1,20 @@
1
+ module Duck
2
+ module_mixin do
3
+ def quack
4
+ :mod_quack
5
+ end
6
+ end
7
+
8
+ class_mixin do
9
+ def quack
10
+ :cls_quack
11
+ end
12
+ end
13
+ end
14
+
15
+
16
+ module Plain
17
+ def flavor
18
+ :vanilla
19
+ end
20
+ end
@@ -0,0 +1,34 @@
1
+ require 'nudgers'
2
+
3
+
4
+ module Includr
5
+ module_mixin do
6
+ include ModNudgr
7
+
8
+ def ping
9
+ :mod_mxn_ping
10
+ end
11
+ end
12
+
13
+ class_mixin do
14
+ include ClsNudgr
15
+
16
+ def ping
17
+ :cls_mxn_ping
18
+ end
19
+ end
20
+ end
21
+
22
+
23
+ module Includrer
24
+ include Includr
25
+ end
26
+
27
+
28
+ class Included
29
+ include Includr
30
+ end
31
+
32
+ class Includedr
33
+ include Includrer
34
+ end
@@ -0,0 +1,76 @@
1
+ [:Meeper, :MeeperCls, :ActiveMeeper, :ActiveMeeperCls, :HyperMeeper, :HyperMeeperCls].each do |mod|
2
+ if Object.const_defined?(mod)
3
+ Object.send(:remove_const, mod)
4
+ end
5
+ end
6
+
7
+
8
+ module Meeper
9
+
10
+ module_mixin do
11
+ def meeper_mixin?
12
+ true
13
+ end
14
+
15
+ def meep
16
+ :meep
17
+ end
18
+ end
19
+
20
+ class_mixin do
21
+ def meeper_class?
22
+ true
23
+ end
24
+
25
+ def says
26
+ :meep
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ module ActiveMeeper
33
+ include Meeper
34
+
35
+ module_mixin do
36
+ def active?
37
+ true
38
+ end
39
+ end
40
+
41
+ class_mixin do
42
+ def active_meeper?
43
+ true
44
+ end
45
+ end
46
+ end
47
+
48
+
49
+ module HyperMeeper
50
+ include ActiveMeeper
51
+
52
+ module_mixin do
53
+ def hyperactive?
54
+ true
55
+ end
56
+ end
57
+
58
+ class_mixin do
59
+ def hyper_meeper?
60
+ true
61
+ end
62
+ end
63
+ end
64
+
65
+
66
+ class MeeperCls
67
+ include Meeper
68
+ end
69
+
70
+ class ActiveMeeperCls
71
+ include ActiveMeeper
72
+ end
73
+
74
+ class HyperMeeperCls
75
+ include HyperMeeper
76
+ end
@@ -0,0 +1,21 @@
1
+ module Pingr
2
+ def ping
3
+ :mod_ping
4
+ end
5
+ end
6
+
7
+
8
+ module ModNudgr
9
+ include Pingr
10
+ def nudge
11
+ :module
12
+ end
13
+ end
14
+
15
+
16
+ module ClsNudgr
17
+ include Pingr
18
+ def nudge
19
+ :class
20
+ end
21
+ end
@@ -0,0 +1,50 @@
1
+ module M
2
+
3
+ module Scoper
4
+ @@cls_attr = :cls
5
+ @inst_attr = :inst
6
+
7
+ module_mixin do
8
+ def cls_attr
9
+ @@cls_attr
10
+ end
11
+
12
+ def inst_attr
13
+ @inst_attr
14
+ end
15
+
16
+ def me
17
+ self
18
+ end
19
+ end
20
+
21
+ class_mixin do
22
+ def cls_attr
23
+ @@cls_attr
24
+ end
25
+
26
+ def inst_attr
27
+ @inst_attr
28
+ end
29
+
30
+ def me
31
+ self
32
+ end
33
+ end
34
+ end
35
+
36
+ module XScoper
37
+ include Scoper
38
+ end
39
+
40
+
41
+ class ScoperCls
42
+ include Scoper
43
+ end
44
+
45
+ class XScoperCls
46
+ include XScoper
47
+ @inst_attr = :xinst
48
+ end
49
+
50
+ end
@@ -0,0 +1,18 @@
1
+ module SansMxn
2
+ end
3
+
4
+ module LazyModExt
5
+ extend_module_mixin SansMxn
6
+ end
7
+
8
+ module LazyClsExt
9
+ extend_class_mixin SansMxn
10
+ end
11
+
12
+ module LazyModMxn
13
+ module_mixin {}
14
+ end
15
+
16
+ module LazyClsMxn
17
+ class_mixin {}
18
+ end
@@ -0,0 +1,120 @@
1
+ module SooprMX
2
+ def giv_er
3
+ [0]
4
+ end
5
+ end
6
+
7
+ module SooprCX
8
+ def giv_em
9
+ [0]
10
+ end
11
+ end
12
+
13
+
14
+ module Soopr1
15
+ extend_module_mixin SooprMX
16
+
17
+ module_mixin do
18
+ def giv_er
19
+ super + [1]
20
+ end
21
+ end
22
+
23
+ class_mixin do
24
+ include SooprCX
25
+
26
+ def giv_em
27
+ [1] + super
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+ module Soopr2
34
+ include Soopr1
35
+
36
+ module_mixin do
37
+ def giv_er
38
+ super + [2]
39
+ end
40
+ end
41
+
42
+ class_mixin do
43
+ def giv_em
44
+ [2] + super
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+ module Soopr3
51
+ include Soopr2
52
+
53
+ module_mixin do
54
+ def giv_er
55
+ super + [3]
56
+ end
57
+ end
58
+
59
+ class_mixin do
60
+ def giv_em
61
+ [3] + super
62
+ end
63
+ end
64
+ end
65
+
66
+
67
+ class SooprC1
68
+ include Soopr1
69
+ end
70
+
71
+ class SooprC2
72
+ include Soopr2
73
+ end
74
+
75
+ class SooprC3
76
+ include Soopr3
77
+ end
78
+
79
+
80
+
81
+ module DooprMX
82
+ def giv_er
83
+ super + [7]
84
+ end
85
+ end
86
+
87
+ module DooprCX
88
+ def giv_em
89
+ [7] + super
90
+ end
91
+ end
92
+
93
+
94
+ module Soopr4
95
+ include Soopr3
96
+ extend_class_mixin DooprCX
97
+
98
+ class_mixin do
99
+ def giv_em
100
+ [9] + super
101
+ end
102
+ end
103
+
104
+ module_mixin do
105
+ include DooprMX
106
+
107
+ def giv_er
108
+ super + [9]
109
+ end
110
+ end
111
+ end
112
+
113
+
114
+ class SooprC4
115
+ include Soopr4
116
+
117
+ def self.giv_em
118
+ [666] + super
119
+ end
120
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mixin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Hersch Stevenson (xian)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-09-04 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: stevenson@persapient.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - LICENSE
25
+ files:
26
+ - lib/metable/instance_methods.rb
27
+ - lib/metable/class_methods.rb
28
+ - lib/mixin.rb
29
+ - lib/metable.rb
30
+ - test/test_subjects/scopers.rb
31
+ - test/test_subjects/meepers.rb
32
+ - test/test_subjects/extenders.rb
33
+ - test/test_subjects/sleepers.rb
34
+ - test/test_subjects/hopons.rb
35
+ - test/test_subjects/nudgers.rb
36
+ - test/test_subjects/includers.rb
37
+ - test/test_subjects/soopers.rb
38
+ - test/mixin_case.rb
39
+ - README
40
+ - LICENSE
41
+ has_rdoc: true
42
+ homepage: http://www.persapient.com/mixin
43
+ post_install_message:
44
+ rdoc_options: []
45
+
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ requirements: []
61
+
62
+ rubyforge_project: mixin
63
+ rubygems_version: 1.2.0
64
+ signing_key:
65
+ specification_version: 2
66
+ summary: An extention to Module that is intended to ease the development of mixins that involve both class and instance methods.
67
+ test_files:
68
+ - test/mixin_case.rb