anaphoric_case 0.0.2 → 0.0.3
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.
- 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:
|