anaphoric_case 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/anaphoric_case/version.rb +1 -1
- data/lib/anaphoric_case.rb +16 -2
- data/spec/anaphoric_case_spec.rb +121 -38
- metadata +10 -10
data/lib/anaphoric_case.rb
CHANGED
@@ -6,6 +6,7 @@ module AnaphoricCase
|
|
6
6
|
# @private
|
7
7
|
attr_accessor :__nest
|
8
8
|
|
9
|
+
# @private
|
9
10
|
def switch_stack
|
10
11
|
Thread.current[:__switch_stack] ||= []
|
11
12
|
end
|
@@ -27,7 +28,10 @@ module Kernel
|
|
27
28
|
# a different value, which will become the return value of #aif
|
28
29
|
def aif result = true, &block
|
29
30
|
if result
|
30
|
-
unless block.nil?
|
31
|
+
unless block.nil?
|
32
|
+
new_result = block.call(*[result].slice(0,block.arity))
|
33
|
+
return new_result
|
34
|
+
end
|
31
35
|
return result
|
32
36
|
end
|
33
37
|
false
|
@@ -51,6 +55,9 @@ module Kernel
|
|
51
55
|
# the cheapest thing.
|
52
56
|
# @param [Object] object -
|
53
57
|
# parameter of all +on+ calls will be compared to this object using +===+
|
58
|
+
# @note if you plan on passing an object which could be nil to the method,
|
59
|
+
# you should call {Object#nil?} on it as your first +on+ condition as otherwise
|
60
|
+
# it will always match the first one.
|
54
61
|
# @yield A block during which the +on+ method will be available - the block is required.
|
55
62
|
# The block is always executed in the context of the receiver of the +switch+ method
|
56
63
|
# so most of the time this is +self+ but if you call +switch+ with an explicit receiver
|
@@ -69,11 +76,18 @@ module Kernel
|
|
69
76
|
# the current switch block in this thread
|
70
77
|
it = AnaphoricCase.switch_stack.last.instance_eval { @it }
|
71
78
|
|
79
|
+
# when the subsumption operator is used in these classes
|
80
|
+
# it basically means "equal" so we ignore it these cases
|
81
|
+
if (it and [Kernel, Fixnum, String,
|
82
|
+
Bignum, Float, Symbol].include? result.method(:===).owner)
|
83
|
+
result_simple = true
|
84
|
+
end
|
85
|
+
|
72
86
|
begin
|
73
87
|
if it and (result === it or result == true)
|
74
88
|
result = Kernel.aif it, &block
|
75
89
|
throw :result, result if result
|
76
|
-
elsif result and not it
|
90
|
+
elsif result and (not it or result_simple)
|
77
91
|
result = Kernel.aif result, &block
|
78
92
|
throw :result, result if result
|
79
93
|
end
|
data/spec/anaphoric_case_spec.rb
CHANGED
@@ -4,14 +4,14 @@ require 'anaphoric_case'
|
|
4
4
|
require 'timeout'
|
5
5
|
|
6
6
|
describe "it is an anaphoric case" do
|
7
|
-
|
7
|
+
|
8
8
|
before :all do
|
9
|
-
class
|
10
|
-
def initialize
|
9
|
+
class Fixture
|
10
|
+
def initialize
|
11
11
|
@array = [1,2,3,4,5]
|
12
12
|
@hash = { :bacon => "cheese", :pie => "sky", :snoopy => "pizza" }
|
13
13
|
@string = "That is quite a mustache you've got there, sheriff."
|
14
|
-
@snitch = 0
|
14
|
+
@snitch = 0
|
15
15
|
end
|
16
16
|
|
17
17
|
def count
|
@@ -19,7 +19,7 @@ describe "it is an anaphoric case" do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def flavors thing
|
22
|
-
@hash[thing]
|
22
|
+
@hash[thing]
|
23
23
|
end
|
24
24
|
|
25
25
|
def compliment
|
@@ -47,7 +47,7 @@ describe "it is an anaphoric case" do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
before :each do
|
50
|
-
@test =
|
50
|
+
@test = Fixture.new
|
51
51
|
end
|
52
52
|
|
53
53
|
profile :all do
|
@@ -109,7 +109,7 @@ describe "it is an anaphoric case" do
|
|
109
109
|
|
110
110
|
it "can execute anaphoric blocks using on" do
|
111
111
|
res = switch do
|
112
|
-
on(false) { |it| it.blah_blah } #this would raise an error if it was ever called
|
112
|
+
on(false) { |it| it.blah_blah } #this would raise an error if it was ever called
|
113
113
|
on(1) { |it| it + 1 }
|
114
114
|
end
|
115
115
|
res.should == 2
|
@@ -119,13 +119,13 @@ describe "it is an anaphoric case" do
|
|
119
119
|
res = switch do
|
120
120
|
on false
|
121
121
|
on nil
|
122
|
-
on { 5 }
|
122
|
+
on { 5 }
|
123
123
|
end
|
124
124
|
res.should == 5
|
125
125
|
|
126
126
|
res = switch do
|
127
127
|
on 1
|
128
|
-
on { 1 }
|
128
|
+
on { 1 }
|
129
129
|
end
|
130
130
|
res.should == 1
|
131
131
|
end
|
@@ -151,7 +151,7 @@ describe "it is an anaphoric case" do
|
|
151
151
|
@test.count.slice!(0,3)
|
152
152
|
@test.instance_eval(&test_test).should == [4,5]
|
153
153
|
@test.count.concat [1,1,1,1]
|
154
|
-
@test.instance_eval(&test_test).should == [4,5,1,1,1,1]
|
154
|
+
@test.instance_eval(&test_test).should == [4,5,1,1,1,1]
|
155
155
|
end
|
156
156
|
|
157
157
|
it "can look in an object if it's not within it" do
|
@@ -167,25 +167,52 @@ describe "it is an anaphoric case" do
|
|
167
167
|
lambda { switch }.should raise_error ArgumentError, "switch requires a block"
|
168
168
|
end
|
169
169
|
|
170
|
+
it "executes in a closure" do
|
171
|
+
blah_blah = 57
|
172
|
+
switch do
|
173
|
+
on(blah_blah < 56) { raise "no!!" }
|
174
|
+
on(blah_blah == 57) { blah_blah = "ok"}
|
175
|
+
end
|
176
|
+
blah_blah.should == "ok"
|
177
|
+
|
178
|
+
module Thingy
|
179
|
+
def thing_method arg
|
180
|
+
arg = switch do
|
181
|
+
on (arg == 5) { arg = "poop" }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
class Boosh
|
187
|
+
include Thingy
|
188
|
+
end
|
189
|
+
|
190
|
+
farts = nil
|
191
|
+
Boosh.new.instance_eval do
|
192
|
+
farts = thing_method(5)
|
193
|
+
end
|
194
|
+
farts.should == "poop"
|
195
|
+
end
|
196
|
+
|
170
197
|
it "can't call on from outside of switch block" do
|
171
198
|
lambda { on }.should raise_error NameError
|
172
199
|
|
173
200
|
# ensure the on method is defined the next time
|
174
201
|
# we call it
|
175
|
-
flag = false
|
202
|
+
flag = false
|
176
203
|
t1 = Thread.new do
|
177
204
|
switch do
|
178
205
|
on false
|
179
|
-
flag = true
|
206
|
+
flag = true
|
180
207
|
sleep 0.1
|
181
208
|
on true
|
182
209
|
end
|
183
210
|
flag = false
|
184
211
|
end
|
185
|
-
|
212
|
+
|
186
213
|
Timeout.timeout(1) { loop until flag == true }
|
187
214
|
|
188
|
-
# should transform the uncaught :throw error into a NameError
|
215
|
+
# should transform the uncaught :throw error into a NameError
|
189
216
|
(self.respond_to? :on).should be true #it's defined in the thread
|
190
217
|
lambda { on }.should raise_error NameError, "on without associated switch"
|
191
218
|
|
@@ -195,11 +222,11 @@ describe "it is an anaphoric case" do
|
|
195
222
|
end
|
196
223
|
|
197
224
|
it "can raise past the (internal) throw" do
|
198
|
-
lambda do
|
225
|
+
lambda do
|
199
226
|
switch do
|
200
|
-
on { |a,b,c| raise ArgumentError }
|
227
|
+
on { |a,b,c| raise ArgumentError }
|
201
228
|
end
|
202
|
-
end.should raise_error ArgumentError
|
229
|
+
end.should raise_error ArgumentError
|
203
230
|
end
|
204
231
|
|
205
232
|
it "can nest safely" do
|
@@ -225,17 +252,38 @@ describe "it is an anaphoric case" do
|
|
225
252
|
res.should == 5
|
226
253
|
end
|
227
254
|
|
228
|
-
it "can be called with explicit receiver" do
|
255
|
+
it "can be called with explicit receiver" do
|
229
256
|
# this makes it act a little bit like "tap"
|
230
257
|
res = @test.switch do
|
231
258
|
on (flavors :lime) { |it| it.blah } #would raise
|
232
|
-
on (flavors :snoopy)
|
259
|
+
on (flavors :snoopy)
|
233
260
|
on { raise 'terribly awry'}
|
234
261
|
end
|
235
262
|
|
236
263
|
res.should == "pizza"
|
237
264
|
end
|
238
265
|
|
266
|
+
it "can be called in the context of BasicObject if you prefix it" do
|
267
|
+
@basic = BasicObject.new
|
268
|
+
res = nil
|
269
|
+
test = @test
|
270
|
+
@basic.instance_eval do
|
271
|
+
res = ::Kernel.switch do
|
272
|
+
on (test.flavors :lime) { |it| nothing }
|
273
|
+
on (test.flavors :snoopy)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
res.should == "pizza"
|
277
|
+
|
278
|
+
lambda do
|
279
|
+
@basic.instance_eval do
|
280
|
+
res = switch do
|
281
|
+
on 1
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end.should raise_error NoMethodError
|
285
|
+
end
|
286
|
+
|
239
287
|
it "can act like a regular case statement if called with a parameter" do
|
240
288
|
test = lambda do |test_obj|
|
241
289
|
res = switch test_obj do
|
@@ -257,7 +305,7 @@ describe "it is an anaphoric case" do
|
|
257
305
|
# its is @test.compliment
|
258
306
|
switch it do
|
259
307
|
#it is STILL @test.compliment
|
260
|
-
on(/mustache/) { |thing| false }
|
308
|
+
on(/mustache/) { |thing| false }
|
261
309
|
#return false to fall through
|
262
310
|
end
|
263
311
|
end
|
@@ -265,29 +313,70 @@ describe "it is an anaphoric case" do
|
|
265
313
|
# which means this should NOT match
|
266
314
|
on(/baron/) { |it| it.blah }
|
267
315
|
# but this should.
|
268
|
-
on(/sheriff/) { |it| it + "okay" }
|
316
|
+
on(/sheriff/) { |it| it + "okay" }
|
269
317
|
end
|
270
318
|
res.should == remember + "okay"
|
271
319
|
end
|
272
320
|
|
321
|
+
it "can operate first-truthy with a parameter" do
|
322
|
+
amazing_proc = proc { |t| true if t.first == false }
|
323
|
+
mixed = lambda do
|
324
|
+
switch @test.count do |arr|
|
325
|
+
on arr.empty? { |it| it } # equal to arr
|
326
|
+
on arr.first { |it| it } # equal to arr.first
|
327
|
+
on(amazing_proc){ |it| it } # equal to arr
|
328
|
+
on { "zomg, not this!" }
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
try_it = proc do
|
333
|
+
mixed.call.should == 1
|
334
|
+
@test.count.clear
|
335
|
+
mixed.call.should == []
|
336
|
+
@test.count << false
|
337
|
+
mixed.call.should == [false]
|
338
|
+
@test.count.clear
|
339
|
+
@test.count << nil
|
340
|
+
mixed.call.should == "zomg, not this!"
|
341
|
+
end
|
342
|
+
|
343
|
+
try_it.call
|
344
|
+
|
345
|
+
@test.count.replace [1,2,3,4,5] #reset it
|
346
|
+
|
347
|
+
# you can acheieve the same functionality by calling it in context
|
348
|
+
# without a parameter
|
349
|
+
|
350
|
+
mixed = lambda do
|
351
|
+
@test.count.switch do
|
352
|
+
on(empty?) { self }
|
353
|
+
on(first) { |it| it }
|
354
|
+
on(amazing_proc.call(self)) { self }
|
355
|
+
on { "zomg, not this!" }
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
try_it.call
|
360
|
+
end
|
361
|
+
|
273
362
|
it "can be called both with and without a parameter" do
|
274
363
|
res = switch do
|
275
364
|
# there is no default __it__
|
276
|
-
on @test.compliment =~ /sheriff/ do |it|
|
365
|
+
on @test.compliment =~ /sheriff/ do |it|
|
277
366
|
# it here is "43" the place where sheriff occures
|
278
367
|
switch it do |ot|
|
279
368
|
on(ot > 43) { raise 'ohnoes' }
|
280
|
-
on(ot < 43) { raise 'ohnoes again'}
|
369
|
+
on(ot < 43) { raise 'ohnoes again'}
|
281
370
|
# this will signal completion
|
282
371
|
on(ot == 43) { 'okay!' }
|
283
372
|
end
|
284
373
|
end
|
285
|
-
# so this will not run
|
374
|
+
# so this will not run
|
286
375
|
on(@test.compliment =~ /baron/) { |it| it.blah }
|
287
376
|
end
|
288
377
|
|
289
378
|
res.should == 'okay!'
|
290
|
-
|
379
|
+
|
291
380
|
res = switch @test.compliment do
|
292
381
|
# this will match
|
293
382
|
on /mustache/ do |it|
|
@@ -297,7 +386,7 @@ describe "it is an anaphoric case" do
|
|
297
386
|
end
|
298
387
|
end
|
299
388
|
end
|
300
|
-
|
389
|
+
|
301
390
|
#so the result of the entire block is the last truthy thing
|
302
391
|
res.should == /poor/
|
303
392
|
|
@@ -322,7 +411,7 @@ describe "it is an anaphoric case" do
|
|
322
411
|
on /that/ do
|
323
412
|
switch "thing" do
|
324
413
|
on /thing/ do
|
325
|
-
"foogle bear"
|
414
|
+
"foogle bear"
|
326
415
|
end
|
327
416
|
end
|
328
417
|
end
|
@@ -339,7 +428,7 @@ describe "it is an anaphoric case" do
|
|
339
428
|
t1 = Thread.new do
|
340
429
|
res1 = switch "this" do
|
341
430
|
on /this/ do
|
342
|
-
switch "that" do
|
431
|
+
switch "that" do
|
343
432
|
on(/that/) { "that" }
|
344
433
|
end
|
345
434
|
end
|
@@ -408,7 +497,7 @@ describe "it is an anaphoric case" do
|
|
408
497
|
|
409
498
|
it "threads?" do
|
410
499
|
res1, res2, res3 = nil, nil, nil
|
411
|
-
|
500
|
+
|
412
501
|
t1 = Thread.new do
|
413
502
|
res1 = switch do
|
414
503
|
on(@test.flavors :lime)
|
@@ -431,11 +520,11 @@ describe "it is an anaphoric case" do
|
|
431
520
|
res3 = switch do
|
432
521
|
on false
|
433
522
|
on nil
|
434
|
-
sleep 0.1
|
523
|
+
sleep 0.1
|
435
524
|
on true
|
436
525
|
end
|
437
526
|
end
|
438
|
-
|
527
|
+
|
439
528
|
Timeout.timeout 1 do
|
440
529
|
loop do
|
441
530
|
t = [t1.status, t2.status, t3.status]
|
@@ -445,14 +534,8 @@ describe "it is an anaphoric case" do
|
|
445
534
|
end
|
446
535
|
|
447
536
|
res1.should == "pizza"
|
448
|
-
res2.should == [1,2,3,4,5]
|
537
|
+
res2.should == [1,2,3,4,5]
|
449
538
|
res3.should == true
|
450
539
|
end
|
451
540
|
end
|
452
541
|
end
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anaphoric_case
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-09-
|
12
|
+
date: 2011-09-29 00:00:00.000000000 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
17
|
-
requirement: &
|
17
|
+
requirement: &10086020 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *10086020
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: simplecov
|
28
|
-
requirement: &
|
28
|
+
requirement: &10085810 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *10085810
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: rspec-prof
|
39
|
-
requirement: &
|
39
|
+
requirement: &10085600 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *10085600
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: i18n
|
50
|
-
requirement: &
|
50
|
+
requirement: &10085390 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,7 +55,7 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *10085390
|
59
59
|
description: ! "You have twenty or so methods, and you want to call the first one
|
60
60
|
that returns something other than nil,\n If the dog is on fire, put it out."
|
61
61
|
email:
|