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 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