moosex 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e9e5e041a9a4a5b6dbc6c7f3172983566bfd071
4
- data.tar.gz: 3922f36665039d14f2b84dd6eb95fb83832479c1
3
+ metadata.gz: adec6f28fb1f2d50839aa7eccc0aca75d59541f2
4
+ data.tar.gz: 4883921244c4bd67a5f767a5cc4cdc03e91c8874
5
5
  SHA512:
6
- metadata.gz: fd4f9224783d8ab1f5dde9d268eb497a2502d29dc67d93e2673cf71c0b941c60754e0b3802baf30e26e2c4034d95d4cfcbcd03b59ab608dccd8582ad1ef2c500
7
- data.tar.gz: b651e838ea0f2920847692eca70f3a2d7ab5678f59936175912cfa20866fde0d5c3481fbfb9d152511ed93f29ebdb5a379f792f7b08717c3eeb7c508b77ab1cc
6
+ metadata.gz: 95cee02f36c62c6e8864fb4aab9cbfacc9d552ca81f29283ae67fef75cb861de24a16a1716e352ad947ff9e1889477957dbf633e2d44969e9c35b10f249fea79
7
+ data.tar.gz: 1a5ae462cf7a223f03ae19433ad8b7a3361e6ce3137610c86395450766f0be01a4de959e1d41a353d9c89cf21b3591d877a8400f38f1d50ca8f2ea4892d8eedf
data/Changelog CHANGED
@@ -1,3 +1,6 @@
1
+ 0.0.14 - 2013-02-05
2
+ - roles with around/before/after basic support #41
3
+
1
4
  0.0.13 - 2013-02-05
2
5
  - change around to receive a lambda #42
3
6
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- moosex (0.0.13)
4
+ moosex (0.0.14)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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
- **IMPORTANT** This behavior is temporary, there is an issue for this [here](https://github.com/peczenyj/MooseX/issues/41 "issue in github").
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
 
@@ -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
- method = instance_method method_name
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
- # __meta.add_after(method_name, block)
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
- method = instance_method method_name
198
+ begin
199
+ method = instance_method method_name
134
200
 
135
- define_method method_name do |*args|
136
- block.call(self,*args)
137
- method.bind(self).call(*args)
138
- end
139
-
140
- # __meta.add_before(method_name, block)
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
- method = instance_method method_name
211
+ begin
212
+ method = instance_method method_name
145
213
 
146
- code = Proc.new do | o, *a|
147
- method.bind(o).call(*a)
148
- end
214
+ code = Proc.new do | o, *a|
215
+ method.bind(o).call(*a)
216
+ end
149
217
 
150
- define_method method_name do |*args|
151
-
152
- block.call(code, self,*args)
153
-
154
- end
155
- # __meta.add_around(method, block)
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)
@@ -1,3 +1,3 @@
1
1
  module MooseX
2
- VERSION = "0.0.13"
2
+ VERSION = "0.0.14"
3
3
  end
@@ -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
@@ -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.13
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-05 00:00:00.000000000 Z
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/complex_spec.rb
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/complex_spec.rb
142
+ - spec/complex_type_spec.rb
143
143
  - spec/foo_spec.rb
144
144
  - spec/hooks_spec.rb
145
145
  - spec/lazy_spec.rb