moosex 0.0.15 → 0.0.16

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: bc3a722220a8aed4beee90b8df3a3c8194433ce2
4
- data.tar.gz: 8818053e9e74a8c21be1fb3549e3d53d8574ba24
3
+ metadata.gz: fcfa29200c1f61890442923acc7dc15d025634f0
4
+ data.tar.gz: fa879cea6cd2145c67216366c944278f09510ac6
5
5
  SHA512:
6
- metadata.gz: 17f3adf263961e0f83551cf15eb92e102f60623173533f70ddce374c72409119d4d032993760f2ada6a1884817ba3c6869104ab2531891da3e576a6249f79e87
7
- data.tar.gz: f87783b850d1e43d0be4eaaf89b66967556387406d767ae80f4709f228f75056055b92137561620a492ff94327996e5caf0885e0ff845473c35982e22c69d9af
6
+ metadata.gz: 258f22f909577942823e51962d8191c9827ed2cf4194bee1cb034a87cf056c0e83f55ce2738bd5769d4b4f021e53dd7855e623a953fe38672927aab3fa9d7833
7
+ data.tar.gz: 729fe046482be2b464dfe0f2709167737fbb88f1b28afe0b8f2215b8ce06b82fa6b38f793ac3df3a360ec11413ae37e2ba94ec8ade4b52df6599c38d454f8a10
data/Changelog CHANGED
@@ -1,3 +1,7 @@
1
+ 0.0.16 - 2013-02-07
2
+ - add currying to handles #46
3
+ - not after/before/around works well with methods who receive a block
4
+
1
5
  0.0.15 - 2013-02-07
2
6
  - after, before, around now accept more than one method name
3
7
  - add basic event support #45
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- moosex (0.0.15)
4
+ moosex (0.0.16)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -167,12 +167,18 @@ Optional.
167
167
 
168
168
  ### coerce
169
169
 
170
- You can try to coerce the attribute value by a lambda before the type check phase. For example you can do
170
+ You can try to coerce the attribute value by a lambda/method before the type check phase. For example you can do
171
171
 
172
172
  ```ruby
173
173
  coerce: lambda{ |new_value| new_value.to_i },
174
174
  ```
175
175
 
176
+ or just
177
+
178
+ ```ruby
179
+ coerce: :to_i,
180
+ ```
181
+
176
182
  to force a convertion to integer. Or flatten one array, convert to symbol, etc. Optional.
177
183
 
178
184
  ### handles
@@ -200,6 +206,63 @@ If you need rename the method, you can specify a Hash:
200
206
  ```
201
207
 
202
208
  Optional.
209
+ #### Currying
210
+
211
+ It is possible curry constant values declaring a pair/hash and set one or more constant values / lambdas
212
+
213
+ ```ruby
214
+ handles: {
215
+ my_method_1: {
216
+ method1: 1
217
+ }
218
+ },
219
+ ```
220
+
221
+ this will curry the constant 1 to the argument list. In other words:
222
+
223
+ ```ruby
224
+ obj.target.method1(1,2,3) # OR
225
+ obj.my_method_1(2,3)
226
+ ```
227
+
228
+ are equivalent. You can curry as many arguments as you can.
229
+
230
+ ```ruby
231
+ handles: {
232
+ my_method_2: {
233
+ method2: [1, lambda{ 2 } ]
234
+ }
235
+ },
236
+ ```
237
+
238
+ will generate
239
+ ```ruby
240
+ obj.target.method1(1,2,3) # OR
241
+ obj.my_method_2(3)
242
+ ```
243
+
244
+ are equivalent. if we find one lambda we will call on runtime.
245
+
246
+ Important: if you need do something more complex ( like manipulate the argument list, etc ) consider use the hook 'around'.
247
+
248
+ ###### But how we can curry arrays?
249
+
250
+ Use Double arrays
251
+
252
+ ```ruby
253
+ handles: {
254
+ my_method_1: {
255
+ method1: [ [1,2,3] ]
256
+ }
257
+ },
258
+ ```
259
+ this will curry the array [1,2,3] to the argument list. In other words:
260
+
261
+ ```ruby
262
+ obj.target.method1([1,2,3],2,3) # OR
263
+ obj.my_method_1(2,3)
264
+ ```
265
+ are equivalent.
203
266
 
204
267
  ### trigger
205
268
 
@@ -732,7 +795,7 @@ ex3 = BuildArgsExample2.new() # x == 4, y == 8
732
795
 
733
796
  ## EVENTS
734
797
 
735
- MooseX has a built-in event system, and it should be useful if you want to avoid after/before hooks ( depends of what is yout problem ).
798
+ MooseX has a built-in event system, and it should be useful if you want to avoid after/before hooks ( depends of what is your problem ).
736
799
 
737
800
  ```ruby
738
801
  require 'moosex'
@@ -779,6 +842,55 @@ e.emit(:error, "...") # will no longer log nothing
779
842
 
780
843
  If you want to restrict how many different events you can handle, you should overload the `has_events` method and return one array of valid events. If you want accept all, you should return nil (default).
781
844
 
845
+ For example, your method should emit many events, in many points, and you can add/remove listeners easily. And Much More!
846
+
847
+ ### Events + Handles / Currying
848
+
849
+ Look this good example:
850
+
851
+ ```ruby
852
+ require 'moosex'
853
+ require 'moosex/event'
854
+
855
+ class EventHandler
856
+ include MooseX
857
+ include MooseX::Event
858
+
859
+ def has_events ; [ :pinged, :ponged ]; end
860
+ end
861
+
862
+ class EventProcessor
863
+ include MooseX
864
+
865
+ has event_handler: {
866
+ is: :ro,
867
+ isa: EventHandler,
868
+ default: lambda{ EventHandler.new }, # EventProcessor HAS ONE EventHandler
869
+ handles: { # Now, lets start to delegate and currying:
870
+ ping: { emit: :pinged }, # ping() is the same of event_handler.emit(:pinged)
871
+ pong: { emit: :ponged }, # pong(x) is the same of event_handler.emit(:pinged,x)
872
+ on_ping: { on: :pinged }, #
873
+ on_pong: { on: :ponged }, # same thing for on_ping / on_pong
874
+ },
875
+ }
876
+ end
877
+
878
+ ep = EventProcessor.new()
879
+
880
+ ep.on_ping do |obj|
881
+ puts "receive ping!"
882
+ end
883
+
884
+ ep.on_pong do |obj, message|
885
+ puts "receive pong with #{message}!"
886
+ end
887
+
888
+ ep.ping # will print "receive ping!"
889
+ ep.pong 1 # will print "receive pong with 1!"
890
+ ```
891
+
892
+ Now, imagine what you can do with a Parametrized Role: we can create all handles based on event names!
893
+
782
894
  ## IMPORTANT
783
895
 
784
896
  This module is experimental. I should test more and more to be possible consider this "production ready". If you find some issue/bug please add here: https://github.com/peczenyj/MooseX/issues
@@ -175,18 +175,18 @@ module MooseX
175
175
  after = @after[method_name]
176
176
  around = @around[method_name]
177
177
 
178
- klass.__meta_define_method(method_name) do |*args|
179
- before.each{|b| b.call(self,*args)}
178
+ klass.__meta_define_method(method_name) do |*args, &proc|
179
+ before.each{|b| b.call(self,*args, &proc)}
180
180
 
181
- original = lambda do |object, *args|
182
- method.bind(object).call(*args)
181
+ original = lambda do |object, *args, &proc|
182
+ method.bind(object).call(*args, &proc)
183
183
  end
184
184
 
185
185
  result = around.inject(original) do |lambda1, lambda2|
186
186
  lambda2.curry[lambda1]
187
- end.call(self, *args)
187
+ end.call(self, *args, &proc)
188
188
 
189
- after.each{|b| b.call(self,*args)}
189
+ after.each{|b| b.call(self,*args, &proc)}
190
190
 
191
191
  result
192
192
  end
@@ -217,9 +217,9 @@ module MooseX
217
217
  begin
218
218
  method = instance_method method_name
219
219
 
220
- define_method method_name do |*args|
221
- result = method.bind(self).call(*args)
222
- block.call(self,*args)
220
+ define_method method_name do |*args, &proc|
221
+ result = method.bind(self).call(*args, &proc)
222
+ block.call(self,*args,&proc)
223
223
  result
224
224
  end
225
225
  rescue => e
@@ -234,9 +234,9 @@ module MooseX
234
234
  begin
235
235
  method = instance_method method_name
236
236
 
237
- define_method method_name do |*args|
238
- block.call(self,*args)
239
- method.bind(self).call(*args)
237
+ define_method method_name do |*args, &proc|
238
+ block.call(self,*args, &proc)
239
+ method.bind(self).call(*args, &proc)
240
240
  end
241
241
  rescue => e
242
242
  MooseX.warn "unable to apply hook before in #{method_name} @ #{self}: #{e}", caller() if self.is_a?(Class)
@@ -248,17 +248,17 @@ module MooseX
248
248
  def around(*methods_name, &block)
249
249
  methods_name.each do |method_name|
250
250
  begin
251
+
251
252
  method = instance_method method_name
252
253
 
253
- code = Proc.new do | o, *a|
254
- method.bind(o).call(*a)
254
+ code = Proc.new do | o, *a, &proc|
255
+ method.bind(o).call(*a,&proc)
255
256
  end
256
257
 
257
- define_method method_name do |*args|
258
-
259
- block.call(code, self,*args)
260
-
261
- end
258
+ define_method method_name do |*args, &proc|
259
+ block.call(code, self,*args, &proc)
260
+ end
261
+
262
262
  rescue => e
263
263
  MooseX.warn "unable to apply hook around in #{method_name} @ #{self}: #{e}", caller() if self.is_a?(Class)
264
264
  __meta.add_around(method_name, block)
@@ -411,7 +411,15 @@ module MooseX
411
411
  end
412
412
 
413
413
  handles.map do |key,value|
414
- { key.to_sym => value.to_sym }
414
+ if value.is_a? Hash
415
+ raise "ops! Handle should accept only one map / currying" unless value.count == 1
416
+
417
+ original, currying = value.shift
418
+
419
+ { key.to_sym => [original.to_sym, currying] }
420
+ else
421
+ { key.to_sym => value.to_sym }
422
+ end
415
423
  end.reduce({}) do |hash,e|
416
424
  hash.merge(e)
417
425
  end
@@ -537,9 +545,26 @@ module MooseX
537
545
 
538
546
  attr_symbol = @attr_symbol
539
547
  @handles.each_pair do | method, target_method |
540
- @methods[method] = Proc.new do |*args|
541
- self.send(attr_symbol).send(target_method, *args)
542
- end
548
+ if target_method.is_a? Array
549
+ original, currying = target_method
550
+
551
+ @methods[method] = Proc.new do |*args, &proc|
552
+
553
+ a1 = [ currying ]
554
+
555
+ if currying.is_a?Proc
556
+ a1 = currying.call()
557
+ elsif currying.is_a? Array
558
+ a1 = currying.map{|c| (c.is_a?(Proc)) ? c.call : c }
559
+ end
560
+
561
+ self.send(attr_symbol).send(original, *a1, *args, &proc)
562
+ end
563
+ else
564
+ @methods[method] = Proc.new do |*args, &proc|
565
+ self.send(attr_symbol).send(target_method, *args, &proc)
566
+ end
567
+ end
543
568
  end
544
569
  end
545
570
 
@@ -59,8 +59,7 @@ module MooseX
59
59
  listener
60
60
  end
61
61
 
62
- before(:add_event_listener, :emit) do |obj, event, *rest|
63
-
62
+ before(:on, :once, :emit) do |obj, event, *rest, &proc|
64
63
  if ! obj.has_events.nil? && ! [ obj.has_events ].flatten.include?(event)
65
64
 
66
65
  raise EventException, "Event '#{event.inspect}' not supported, this class only allow: #{obj.has_events.inspect}",caller
@@ -1,3 +1,3 @@
1
1
  module MooseX
2
- VERSION = "0.0.15"
2
+ VERSION = "0.0.16"
3
3
  end
@@ -0,0 +1,40 @@
1
+ require 'moosex'
2
+ require 'moosex/event'
3
+
4
+ class EventHandler
5
+ include MooseX
6
+ include MooseX::Event
7
+
8
+ def has_events
9
+ [ :pinged, :ponged ]
10
+ end
11
+ end
12
+
13
+ class EventProcessor
14
+ include MooseX
15
+
16
+ has event_handler: {
17
+ is: :ro,
18
+ isa: EventHandler,
19
+ default: lambda{ EventHandler.new },
20
+ handles: {
21
+ ping: { emit: :pinged },
22
+ pong: { emit: :ponged },
23
+ on_ping: { on: :pinged },
24
+ on_pong: { on: :ponged },
25
+ },
26
+ }
27
+ end
28
+
29
+ ep = EventProcessor.new()
30
+
31
+ ep.on_ping do |x|
32
+ puts "receive ping!"
33
+ end
34
+
35
+ ep.on_pong do |obj, message|
36
+ puts "receive pong with #{message}!"
37
+ end
38
+
39
+ ep.ping # will print "receive ping!"
40
+ ep.pong 1 # will print "receive pong!"
@@ -12,7 +12,7 @@ class CoerceTest
12
12
  has attribute_rw: {
13
13
  is: :rw,
14
14
  isa: Integer,
15
- coerce: lambda {|value| value.to_i },
15
+ coerce: :to_i,
16
16
  }
17
17
 
18
18
  has attribute_lazy: {
@@ -161,4 +161,4 @@ describe EventExample2 do
161
161
 
162
162
  e.emit(:xxx)
163
163
  end
164
- end
164
+ end
@@ -120,4 +120,98 @@ describe "OtherPoint4D" do
120
120
  p.z.should == 0
121
121
  p.t.should == 0
122
122
  end
123
- end
123
+ end
124
+
125
+ module ModuleHWB
126
+ include MooseX
127
+
128
+ requires :info
129
+
130
+ around(:call_with) do |original, object,x,&proc|
131
+ object.info(1,x)
132
+
133
+ result= original.call(object,x,&proc)
134
+
135
+ object.info(2,result)
136
+
137
+ result
138
+ end
139
+
140
+ before(:call_with) do |object,x, &k|
141
+ object.info(3, x)
142
+ end
143
+
144
+ after(:call_with) do |object,x,&k|
145
+ object.info(4, x)
146
+ end
147
+ end
148
+
149
+ class HooksWithBlocks
150
+ include MooseX
151
+
152
+ has logger: { is: :rw, handles: :info }
153
+
154
+ def call_with(x)
155
+ yield(x)
156
+ #proc.call(x)
157
+ end
158
+
159
+ include ModuleHWB
160
+ end
161
+
162
+ class HooksWithBlocks2
163
+ include MooseX
164
+
165
+ has logger: { is: :rw, handles: :info }
166
+
167
+ def call_with(x, &proc)
168
+ #yield(x)
169
+ proc.call(x)
170
+ end
171
+
172
+ around(:call_with) do |original, object,x,&proc|
173
+ object.info(1,x)
174
+
175
+ result= original.call(object,x,&proc)
176
+
177
+ object.info(2,result)
178
+
179
+ result
180
+ end
181
+
182
+ before(:call_with) do |object,x, &k|
183
+ object.info(3, x)
184
+ end
185
+
186
+ after(:call_with) do |object,x,&k|
187
+ object.info(4, x)
188
+ end
189
+ end
190
+
191
+ describe HooksWithBlocks do
192
+ it "should call all hooks" do
193
+ logger = double
194
+ logger.should_receive(:info).with(3,7).once()
195
+ logger.should_receive(:info).with(1,7).once()
196
+ logger.should_receive(:info).with(2,8).once()
197
+ logger.should_receive(:info).with(4,7).once()
198
+
199
+ x = HooksWithBlocks.new(logger: logger)
200
+ x.call_with(7){|x| x+1}
201
+ end
202
+ end
203
+
204
+ describe HooksWithBlocks2 do
205
+ it "should call all hooks" do
206
+ logger = double
207
+ logger.should_receive(:info).with(3,7).once()
208
+ logger.should_receive(:info).with(1,7).once()
209
+ logger.should_receive(:info).with(2,8).once()
210
+ logger.should_receive(:info).with(4,7).once()
211
+
212
+ x = HooksWithBlocks2.new(logger: logger)
213
+ x.call_with(7) do |x|
214
+ x+1
215
+ end
216
+ end
217
+ end
@@ -5,17 +5,37 @@ class ProxyToTarget
5
5
 
6
6
  has target: {
7
7
  is: :ro,
8
- default: lambda { Target.new }, # default, new instace of Target
9
- handles: { # handles is for delegation,
10
- my_method_x: :method_x, # inject methods with new names
11
- my_method_y: :method_y, # old => obj.target.method_x
12
- }, # now => obj.my_method_x
8
+ default: lambda { Target.new }, # default, new instace of Target
9
+ handles: { # handles is for delegation,
10
+ my_method_x: :method_x, # inject methods with new names
11
+ my_method_y: :method_y, # old => obj.target.method_x , now => obj.my_method_x
12
+ my_method_y_with_1: { # currying!!!
13
+ method_y: 1, # call obj.mymethod_z(2,3) is the equivalent to
14
+ }, # call obj.target.method_z(1,2,3)
15
+ my_method_y_with_lambda: { # currying!!!
16
+ method_y: lambda{ 1 }, # call obj.mymethod_z(2,3) is the equivalent to
17
+ }, # call obj.target.method_z(1,2,3)
18
+ my_method_z_with_array: {
19
+ method_z: [1,lambda{ 2 } ,3]
20
+ },
21
+ my_method_k_with_literal_array: {
22
+ method_k: [[1,2,3]]
23
+ },
24
+ my_method_k_with_literal_array2: {
25
+ method_k: [ lambda{ [1,2,3] } ]
26
+ },
27
+ my_method_k_with_literal_array3: {
28
+ method_k: lambda{ [[1,2,3]] }
29
+ }
30
+ }
13
31
  }
14
32
  end
15
33
 
16
34
  module TargetModule
17
35
  def method_x; 1024; end # works with simple methods
18
36
  def method_y(a,b,c); a + b + c; end # or methods with arguments
37
+ def method_z(*args); args.reduce(:+); end
38
+ def method_k(array); array.count; end
19
39
  end
20
40
 
21
41
  class Target
@@ -36,7 +56,48 @@ describe "ProxyToTarget" do
36
56
  p.target.method_y(1,2,3).should == 6
37
57
  p.my_method_y(1,2,3).should == 6
38
58
  end
59
+
60
+ it "should delegate method_y to the target with currying" do
61
+ p = ProxyToTarget.new
62
+
63
+ p.target.method_y(1,2,3).should == 6
64
+ p.my_method_y_with_1(2,3).should == 6
65
+ end
66
+
67
+ it "should delegate method_y to the target with currying as lambda" do
68
+ p = ProxyToTarget.new
69
+
70
+ p.target.method_y(1,2,3).should == 6
71
+ p.my_method_y_with_lambda(2,3).should == 6
72
+ end
73
+
74
+ it "should delegate method_z to the target with currying (many args) as lambda" do
75
+ p = ProxyToTarget.new
76
+
77
+ p.target.method_z(1,2,3,4).should == 10
78
+ p.my_method_z_with_array(4).should == 10
79
+ end
80
+
81
+ it "should delegate method_k to the target with currying (many args)" do
82
+ p = ProxyToTarget.new
83
+
84
+ p.target.method_k([1,2,3]).should == 3
85
+ p.my_method_k_with_literal_array().should == 3
86
+ end
39
87
 
88
+ it "should delegate method_k to the target with currying (many args) as lambda" do
89
+ p = ProxyToTarget.new
90
+
91
+ p.target.method_k([1,2,3]).should == 3
92
+ p.my_method_k_with_literal_array2().should == 3
93
+ end
94
+
95
+ it "should delegate method_k to the target with currying (many args) as lambda (2)" do
96
+ p = ProxyToTarget.new
97
+
98
+ p.target.method_k([1,2,3]).should == 3
99
+ p.my_method_k_with_literal_array3().should == 3
100
+ end
40
101
  it "should inject method_y" do
41
102
  p = ProxyToTarget.new
42
103
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moosex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Peczenyj
@@ -91,6 +91,7 @@ files:
91
91
  - lib/moosex/types.rb
92
92
  - lib/moosex/version.rb
93
93
  - moosex.gemspec
94
+ - samples/events.rb
94
95
  - samples/point.rb
95
96
  - samples/roles.rb
96
97
  - spec/baserole_spec.rb