moosex 0.0.13 → 0.0.14
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.
- checksums.yaml +4 -4
- data/Changelog +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +3 -1
- data/lib/moosex.rb +96 -26
- data/lib/moosex/version.rb +1 -1
- data/spec/{complex_spec.rb → complex_type_spec.rb} +0 -0
- data/spec/hooks_spec.rb +28 -1
- data/spec/role_spec.rb +130 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adec6f28fb1f2d50839aa7eccc0aca75d59541f2
|
4
|
+
data.tar.gz: 4883921244c4bd67a5f767a5cc4cdc03e91c8874
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95cee02f36c62c6e8864fb4aab9cbfacc9d552ca81f29283ae67fef75cb861de24a16a1716e352ad947ff9e1889477957dbf633e2d44969e9c35b10f249fea79
|
7
|
+
data.tar.gz: 1a5ae462cf7a223f03ae19433ad8b7a3361e6ce3137610c86395450766f0be01a4de959e1d41a353d9c89cf21b3591d877a8400f38f1d50ca8f2ea4892d8eedf
|
data/Changelog
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -384,7 +384,9 @@ instead redefine the 'clear!' method in the subclass, we just add a piece of cod
|
|
384
384
|
|
385
385
|
Each after/before/around will **redefine** the original method in order. If you want override the method in some subclass, you will loose all hooks. The best way to preserve all hooks is using after/before/around to modify the behavior if possible.
|
386
386
|
|
387
|
-
|
387
|
+
Roles and Hooks
|
388
|
+
|
389
|
+
If you try to add one role to a method who does not exists yet, this will be added in the next class. BE CAREFUL, THIS IS EXPERIMENTAL! PLEASE REPORT ANY BUG IF YOU FIND!!!
|
388
390
|
|
389
391
|
### after
|
390
392
|
|
data/lib/moosex.rb
CHANGED
@@ -34,6 +34,9 @@ module MooseX
|
|
34
34
|
|
35
35
|
return unless x.is_a? Class
|
36
36
|
|
37
|
+
x.__meta.load_hooks(self.__meta)
|
38
|
+
self.__meta.init_klass(x)
|
39
|
+
|
37
40
|
x.__meta.requires.each do |method|
|
38
41
|
unless x.public_instance_methods.include? method
|
39
42
|
warn "[MooseX] you must implement method '#{method}' in #{x} #{x.class}: required" if $MOOSEX_DEBUG
|
@@ -46,6 +49,9 @@ module MooseX
|
|
46
49
|
unless c.respond_to? :__meta
|
47
50
|
c.class_exec do
|
48
51
|
define_singleton_method(:__meta) { meta }
|
52
|
+
define_singleton_method(:__meta_define_method) do |method_name, &proc|
|
53
|
+
define_method(method_name, proc)
|
54
|
+
end
|
49
55
|
end
|
50
56
|
end
|
51
57
|
|
@@ -74,11 +80,16 @@ module MooseX
|
|
74
80
|
end
|
75
81
|
|
76
82
|
class Meta
|
77
|
-
attr_reader :attrs, :requires
|
83
|
+
attr_reader :attrs, :requires, :before, :after, :around
|
78
84
|
|
79
85
|
def initialize(old_meta=nil)
|
86
|
+
@initialized = false
|
80
87
|
@attrs = {}
|
81
88
|
@requires = []
|
89
|
+
@before = Hash.new { |hash, key| hash[key] = [] }
|
90
|
+
@after = Hash.new { |hash, key| hash[key] = [] }
|
91
|
+
@around = Hash.new { |hash, key| hash[key] = [] }
|
92
|
+
|
82
93
|
if old_meta
|
83
94
|
old_meta.attrs.each_pair do |key, value|
|
84
95
|
@attrs[key] = value.clone
|
@@ -94,6 +105,18 @@ module MooseX
|
|
94
105
|
@requires += other_meta.requires
|
95
106
|
end
|
96
107
|
|
108
|
+
def load_hooks(other_meta)
|
109
|
+
other_meta.before.each_pair do |m, b|
|
110
|
+
@before[m] += b.clone
|
111
|
+
end
|
112
|
+
other_meta.after.each_pair do |m, b|
|
113
|
+
@after[m] += b.clone
|
114
|
+
end
|
115
|
+
other_meta.around.each_pair do |m, b|
|
116
|
+
@around[m] += b.clone
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
97
120
|
def add(attr)
|
98
121
|
@attrs[attr.attr_symbol] = attr
|
99
122
|
end
|
@@ -102,6 +125,46 @@ module MooseX
|
|
102
125
|
@requires << method
|
103
126
|
end
|
104
127
|
|
128
|
+
def add_before(method_name, block)
|
129
|
+
@before[method_name] << block.clone
|
130
|
+
end
|
131
|
+
|
132
|
+
def add_after(method_name, block)
|
133
|
+
@after[method_name] << block.clone
|
134
|
+
end
|
135
|
+
|
136
|
+
def add_around(method_name, block)
|
137
|
+
@around[method_name] << block.clone
|
138
|
+
end
|
139
|
+
|
140
|
+
def init_klass(klass)
|
141
|
+
#return if @initialized
|
142
|
+
|
143
|
+
[@before.keys + @after.keys + @around.keys].flatten.uniq.each do |method_name|
|
144
|
+
method = klass.instance_method method_name
|
145
|
+
|
146
|
+
before = @before[method_name]
|
147
|
+
after = @after[method_name]
|
148
|
+
around = @around[method_name]
|
149
|
+
|
150
|
+
klass.__meta_define_method(method_name) do |*args|
|
151
|
+
before.each{|b| b.call(self,*args)}
|
152
|
+
|
153
|
+
original = lambda do |object, *args|
|
154
|
+
method.bind(object).call(*args)
|
155
|
+
end
|
156
|
+
|
157
|
+
result = around.inject(original) do |lambda1, lambda2|
|
158
|
+
lambda2.curry[lambda1]
|
159
|
+
end.call(self, *args)
|
160
|
+
|
161
|
+
after.each{|b| b.call(self,*args)}
|
162
|
+
|
163
|
+
result
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
105
168
|
def init(object, args)
|
106
169
|
@attrs.each_pair{ |symbol, attr| attr.init(object, args) }
|
107
170
|
|
@@ -118,41 +181,48 @@ module MooseX
|
|
118
181
|
|
119
182
|
module Core
|
120
183
|
def after(method_name, &block)
|
121
|
-
|
122
|
-
|
123
|
-
define_method method_name do |*args|
|
124
|
-
result = method.bind(self).call(*args)
|
125
|
-
block.call(self,*args)
|
126
|
-
result
|
127
|
-
end
|
184
|
+
begin
|
185
|
+
method = instance_method method_name
|
128
186
|
|
129
|
-
|
187
|
+
define_method method_name do |*args|
|
188
|
+
result = method.bind(self).call(*args)
|
189
|
+
block.call(self,*args)
|
190
|
+
result
|
191
|
+
end
|
192
|
+
rescue => e
|
193
|
+
__meta.add_after(method_name, block)
|
194
|
+
end
|
130
195
|
end
|
131
196
|
|
132
197
|
def before(method_name, &block)
|
133
|
-
|
198
|
+
begin
|
199
|
+
method = instance_method method_name
|
134
200
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
201
|
+
define_method method_name do |*args|
|
202
|
+
block.call(self,*args)
|
203
|
+
method.bind(self).call(*args)
|
204
|
+
end
|
205
|
+
rescue => e
|
206
|
+
__meta.add_before(method_name, block)
|
207
|
+
end
|
141
208
|
end
|
142
209
|
|
143
210
|
def around(method_name, &block)
|
144
|
-
|
211
|
+
begin
|
212
|
+
method = instance_method method_name
|
145
213
|
|
146
|
-
|
147
|
-
|
148
|
-
|
214
|
+
code = Proc.new do | o, *a|
|
215
|
+
method.bind(o).call(*a)
|
216
|
+
end
|
149
217
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
218
|
+
define_method method_name do |*args|
|
219
|
+
|
220
|
+
block.call(code, self,*args)
|
221
|
+
|
222
|
+
end
|
223
|
+
rescue => e
|
224
|
+
__meta.add_around(method_name, block)
|
225
|
+
end
|
156
226
|
end
|
157
227
|
|
158
228
|
def requires(*methods)
|
data/lib/moosex/version.rb
CHANGED
File without changes
|
data/spec/hooks_spec.rb
CHANGED
@@ -80,6 +80,7 @@ class OtherPoint3D < OtherPoint
|
|
80
80
|
object.z = 0
|
81
81
|
end
|
82
82
|
end
|
83
|
+
|
83
84
|
describe "OtherPoint3D" do
|
84
85
|
it "should clear a 3d point" do
|
85
86
|
p = OtherPoint3D.new(x: 1, y: 2, z: 3)
|
@@ -93,4 +94,30 @@ describe "OtherPoint3D" do
|
|
93
94
|
p.y.should == 0
|
94
95
|
p.z.should == 0
|
95
96
|
end
|
96
|
-
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class OtherPoint4D < OtherPoint3D
|
100
|
+
|
101
|
+
has t: { is: :rw, required: true }
|
102
|
+
|
103
|
+
after :clear! do |object|
|
104
|
+
object.t = 0
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "OtherPoint4D" do
|
109
|
+
it "should clear a 3d point" do
|
110
|
+
p = OtherPoint4D.new(x: 1, y: 2, z: 3, t: 4)
|
111
|
+
p.x.should == 1
|
112
|
+
p.y.should == 2
|
113
|
+
p.z.should == 3
|
114
|
+
p.t.should == 4
|
115
|
+
|
116
|
+
p.clear!
|
117
|
+
|
118
|
+
p.x.should == 0
|
119
|
+
p.y.should == 0
|
120
|
+
p.z.should == 0
|
121
|
+
p.t.should == 0
|
122
|
+
end
|
123
|
+
end
|
data/spec/role_spec.rb
CHANGED
@@ -81,3 +81,133 @@ describe ComplexRole::WrongClass do
|
|
81
81
|
"you must implement method 'equal' in ComplexRole::WrongClass: required")
|
82
82
|
end
|
83
83
|
end
|
84
|
+
|
85
|
+
module AfterBefore
|
86
|
+
module Sayhi
|
87
|
+
include MooseX
|
88
|
+
requires :say
|
89
|
+
before(:say) do |object, message|
|
90
|
+
object.logger.before_say_2(message)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
module Sayhi2
|
95
|
+
include MooseX
|
96
|
+
requires :say
|
97
|
+
after(:say) do |object, message|
|
98
|
+
object.logger.after_say_2(message)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
module Sayhi3
|
103
|
+
include MooseX
|
104
|
+
requires :say
|
105
|
+
around(:say) do |lambda, object, message|
|
106
|
+
object.logger.around_say_2(message)
|
107
|
+
v = lambda.call(object,message + 1)
|
108
|
+
object.logger.around_say_2(message)
|
109
|
+
v + 2
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class Undertest
|
114
|
+
include MooseX
|
115
|
+
has logger: { is: :rw, required: true }
|
116
|
+
|
117
|
+
def say(message)
|
118
|
+
self.logger.say(message)
|
119
|
+
message
|
120
|
+
end
|
121
|
+
|
122
|
+
around(:say) do |lambda, object, message|
|
123
|
+
object.logger.around_say_1(message)
|
124
|
+
v = lambda.call(object,message + 1)
|
125
|
+
object.logger.around_say_1(message)
|
126
|
+
v + 1
|
127
|
+
end
|
128
|
+
|
129
|
+
after(:say) do |object, message|
|
130
|
+
object.logger.after_say_1(message)
|
131
|
+
end
|
132
|
+
|
133
|
+
before(:say) do |object, message|
|
134
|
+
object.logger.before_say_1(message)
|
135
|
+
end
|
136
|
+
|
137
|
+
include Sayhi
|
138
|
+
include Sayhi2
|
139
|
+
include Sayhi3
|
140
|
+
|
141
|
+
after(:say) do |object, message|
|
142
|
+
object.logger.after_say_3(message)
|
143
|
+
end
|
144
|
+
|
145
|
+
before(:say) do |object, message|
|
146
|
+
object.logger.before_say_3(message)
|
147
|
+
end
|
148
|
+
|
149
|
+
around(:say) do |lambda, object, message|
|
150
|
+
object.logger.around_say_3(message)
|
151
|
+
v = lambda.call(object,message + 1)
|
152
|
+
object.logger.around_say_3(message)
|
153
|
+
v + 1
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class Undertest2 < Undertest
|
158
|
+
def say(x) ; self.logger.say(x); 2*x; end
|
159
|
+
include Sayhi; include Sayhi3
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "AfterBefore::Undertest" do
|
164
|
+
it "should print two messages" do
|
165
|
+
logger = double()
|
166
|
+
|
167
|
+
logger.should_receive(:around_say_3).with(1).once()
|
168
|
+
|
169
|
+
logger.should_receive(:before_say_3).with(2).once()
|
170
|
+
|
171
|
+
logger.should_receive(:around_say_2).with(2).once()
|
172
|
+
|
173
|
+
logger.should_receive(:before_say_2).with(3).once()
|
174
|
+
|
175
|
+
logger.should_receive(:before_say_1).with(3).once()
|
176
|
+
|
177
|
+
logger.should_receive(:around_say_1).with(3).once()
|
178
|
+
|
179
|
+
logger.should_receive(:say).with(4).once()
|
180
|
+
|
181
|
+
logger.should_receive(:around_say_1).with(3).once()
|
182
|
+
|
183
|
+
logger.should_receive(:after_say_1).with(3).once()
|
184
|
+
|
185
|
+
logger.should_receive(:after_say_2).with(3).once()
|
186
|
+
|
187
|
+
logger.should_receive(:around_say_2).with(2).once()
|
188
|
+
|
189
|
+
logger.should_receive(:after_say_3).with(2).once()
|
190
|
+
|
191
|
+
logger.should_receive(:around_say_3).with(1).once()
|
192
|
+
|
193
|
+
u = AfterBefore::Undertest.new(logger: logger)
|
194
|
+
u.say(1).should == 8
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "AfterBefore::Undertest2" do
|
199
|
+
it "should print two messages" do
|
200
|
+
logger = double()
|
201
|
+
|
202
|
+
logger.should_receive(:before_say_2).with(2).once()
|
203
|
+
|
204
|
+
logger.should_receive(:around_say_2).with(1).once()
|
205
|
+
|
206
|
+
logger.should_receive(:say).with(2).once()
|
207
|
+
|
208
|
+
logger.should_receive(:around_say_2).with(1).once()
|
209
|
+
|
210
|
+
u = AfterBefore::Undertest2.new(logger: logger)
|
211
|
+
u.say(1).should == 6 # 1 -> 1+1 -> 2*2 -> 4+2
|
212
|
+
end
|
213
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moosex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Peczenyj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -97,7 +97,7 @@ files:
|
|
97
97
|
- spec/build_spec.rb
|
98
98
|
- spec/buildargs_spec.rb
|
99
99
|
- spec/coerce_spec.rb
|
100
|
-
- spec/
|
100
|
+
- spec/complex_type_spec.rb
|
101
101
|
- spec/foo_spec.rb
|
102
102
|
- spec/hooks_spec.rb
|
103
103
|
- spec/lazy_spec.rb
|
@@ -139,7 +139,7 @@ test_files:
|
|
139
139
|
- spec/build_spec.rb
|
140
140
|
- spec/buildargs_spec.rb
|
141
141
|
- spec/coerce_spec.rb
|
142
|
-
- spec/
|
142
|
+
- spec/complex_type_spec.rb
|
143
143
|
- spec/foo_spec.rb
|
144
144
|
- spec/hooks_spec.rb
|
145
145
|
- spec/lazy_spec.rb
|