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.
@@ -1,3 +1,3 @@
1
1
  module AnaphoricCase
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -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? then result = block.call(*[result].slice(0,block.arity)) end
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
@@ -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 Harness
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 = Harness.new
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.2
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-15 00:00:00.000000000 -05:00
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: &3997360 !ruby/object:Gem::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: *3997360
25
+ version_requirements: *10086020
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: simplecov
28
- requirement: &3997150 !ruby/object:Gem::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: *3997150
36
+ version_requirements: *10085810
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: rspec-prof
39
- requirement: &3996940 !ruby/object:Gem::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: *3996940
47
+ version_requirements: *10085600
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: i18n
50
- requirement: &3996730 !ruby/object:Gem::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: *3996730
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: