mame-dynamicwind 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ === 1.0.1 / 2008-11-21
2
+ * lib/dynamicwind.rb (dynamicwind, __switch): before/after procs should be
3
+ called in a dynamic context of a corresponding dynamicwind.
4
+
5
+ * test/test_dynamicwind.rb: add some tests.
6
+
1
7
  === 1.0.0 / 2008-11-20
2
8
 
3
9
  * 1 major enhancement
@@ -4,7 +4,7 @@ rescue LoadError
4
4
  end
5
5
 
6
6
  module DynamicWind
7
- VERSION = '1.0.0'
7
+ VERSION = '1.0.1'
8
8
 
9
9
  Stack = Struct.new(:fst, :snd, :next)
10
10
 
@@ -18,8 +18,17 @@ module DynamicWind
18
18
  end
19
19
 
20
20
  def dynamicwind(before, thunk, after)
21
+ before_ = after_ = nil
22
+ if ctn_before = __callcc_orig {|c| before_ = c; false }
23
+ before.call
24
+ ctn_before.call
25
+ end
26
+ if ctn_after = __callcc_orig {|c| after_ = c; false }
27
+ after.call
28
+ ctn_after.call
29
+ end
21
30
  mark = __top
22
- __switch(Stack[[before, nil], [nil, after], mark])
31
+ __switch(Stack[[before_, nil], [nil, after_], mark])
23
32
  thunk.call ensure __switch(mark)
24
33
  end
25
34
 
@@ -35,7 +44,7 @@ module DynamicWind
35
44
  return if __top.equal?(mark)
36
45
  __switch(mark.next)
37
46
  fst, snd = mark.fst, mark.snd
38
- fst.first.call if fst.first
47
+ __callcc_orig {|c| fst.first.call(c) } if fst.first
39
48
  __top.fst = snd
40
49
  __top.snd = fst
41
50
  __top.next = mark
@@ -43,7 +52,7 @@ module DynamicWind
43
52
  __top.fst = nil
44
53
  __top.snd = nil
45
54
  __top.next = nil
46
- fst.last.call if fst.last
55
+ __callcc_orig {|c| fst.last.call(c) } if fst.last
47
56
  end
48
57
  end
49
58
 
@@ -73,7 +73,172 @@ class TestDynamicWind < Test::Unit::TestCase
73
73
  assert_equal([:before, :thunk1, :thunk2, :after, :end, :before, :thunk3, :after, :end], ary)
74
74
  end
75
75
 
76
- def test_callcc_in_before
76
+ def test_jump_from_before_to_before
77
+ ary = []
78
+ ctn = nil
79
+ i = 0
80
+ while i <= 1
81
+ dynamicwind(
82
+ proc do
83
+ ary << :before1
84
+ ctn.call if ctn
85
+ ary << :before2
86
+ callcc {|c| ctn = c }
87
+ ary << :before3
88
+ end,
89
+ proc { ary << :thunk },
90
+ proc { ary << :after }
91
+ )
92
+ ary << :end
93
+ i += 1
94
+ end
95
+ assert_equal([:before1, :before2, :before3, :thunk, :after, :end, :before1, :before3, :thunk, :after, :end], ary)
96
+ end
97
+
98
+ def test_jump_from_before_to_thunk
99
+ ary = []
100
+ ctn = nil
101
+ flag = true
102
+ i = 0
103
+ while i <= 1
104
+ dynamicwind(
105
+ proc do
106
+ ary << :before1
107
+ (flag = false; ctn.call) if ctn && flag
108
+ ary << :before2
109
+ end,
110
+ proc do
111
+ ary << :thunk1
112
+ callcc {|c| ctn = c }
113
+ ary << :thunk2
114
+ end,
115
+ proc { ary << :after }
116
+ )
117
+ ary << :end
118
+ i += 1
119
+ end
120
+ assert_equal([:before1, :before2, :thunk1, :thunk2, :after, :end, :before1, :before1, :before2, :thunk2, :after, :end], ary)
121
+ end
122
+
123
+ def test_jump_from_before_to_after
124
+ ary = []
125
+ ctn = nil
126
+ i = 0
127
+ while i <= 1
128
+ dynamicwind(
129
+ proc do
130
+ ary << :before1
131
+ ctn.call if ctn
132
+ ary << :before2
133
+ end,
134
+ proc { ary << :thunk },
135
+ proc do
136
+ ary << :after1
137
+ callcc {|c| ctn = c }
138
+ ary << :after2
139
+ end
140
+ )
141
+ ary << :end
142
+ i += 1
143
+ end
144
+ assert_equal([:before1, :before2, :thunk, :after1, :after2, :end, :before1, :after2, :end], ary)
145
+ end
146
+
147
+ def test_jump_from_thunk_to_before
148
+ ary = []
149
+ ctn = nil
150
+ flag = true
151
+ dynamicwind(
152
+ proc do
153
+ ary << :before1
154
+ callcc {|c| ctn = c }
155
+ ary << :before2
156
+ end,
157
+ proc do
158
+ ary << :thunk1
159
+ (flag = false; ctn.call) if flag
160
+ ary << :thunk2
161
+ end,
162
+ proc { ary << :after }
163
+ )
164
+ assert_equal([:before1, :before2, :thunk1, :after, :before2, :thunk1, :thunk2, :after], ary)
165
+ end
166
+
167
+ def test_jump_from_thunk_to_before_2
168
+ ary = []
169
+ ctn = nil
170
+ flag = true
171
+ i = 0
172
+ while i <= 1
173
+ dynamicwind(
174
+ proc do
175
+ ary << :before1
176
+ callcc {|c| ctn = c } if i == 0
177
+ ary << :before2
178
+ end,
179
+ proc do
180
+ ary << :thunk1
181
+ (flag = false; ctn.call) if i == 1 && flag
182
+ ary << :thunk2
183
+ end,
184
+ proc { ary << :after }
185
+ )
186
+ ary << :end
187
+ i += 1
188
+ end
189
+ assert_equal([:before1, :before2, :thunk1, :thunk2, :after, :end, :before1, :before2, :thunk1, :after, :before2, :thunk1, :thunk2, :after, :end], ary)
190
+ end
191
+
192
+ def test_jump_from_thunk_to_thunk
193
+ ary = []
194
+ ctn = nil
195
+ flag = true
196
+ i = 0
197
+ while i <= 1
198
+ dynamicwind(
199
+ proc do
200
+ ary << :before1
201
+ callcc {|c| ctn = c } if i == 0
202
+ ary << :before2
203
+ end,
204
+ proc do
205
+ ary << :thunk1
206
+ (flag = false; ctn.call) if i == 1 && flag
207
+ ary << :thunk2
208
+ end,
209
+ proc { ary << :after }
210
+ )
211
+ ary << :end
212
+ i += 1
213
+ end
214
+ assert_equal([:before1, :before2, :thunk1, :thunk2, :after, :end, :before1, :before2, :thunk1, :after, :before2, :thunk1, :thunk2, :after, :end], ary)
215
+ end
216
+
217
+ def test_jump_from_thunk_to_after
218
+ ary = []
219
+ ctn = nil
220
+ i = 0
221
+ while i <= 1
222
+ dynamicwind(
223
+ proc { ary << :before },
224
+ proc do
225
+ ary << :thunk1
226
+ ctn.call if ctn
227
+ ary << :thunk2
228
+ end,
229
+ proc do
230
+ ary << :after1
231
+ callcc {|c| ctn = c }
232
+ ary << :after2
233
+ end
234
+ )
235
+ ary << :end
236
+ i += 1
237
+ end
238
+ assert_equal([:before, :thunk1, :thunk2, :after1, :after2, :end, :before, :thunk1, :after1, :after2, :after2, :end], ary)
239
+ end
240
+
241
+ def test_jump_from_after_to_before
77
242
  ary = []
78
243
  ctn = nil
79
244
  flag = true
@@ -93,6 +258,98 @@ class TestDynamicWind < Test::Unit::TestCase
93
258
  assert_equal([:before1, :before2, :thunk, :after1, :before2, :thunk, :after1, :after2], ary)
94
259
  end
95
260
 
261
+ def test_jump_from_after_to_before_2
262
+ ary = []
263
+ ctn = nil
264
+ flag = true
265
+ i = 0
266
+ while i <= 1
267
+ dynamicwind(
268
+ proc do
269
+ ary << :before1
270
+ callcc {|c| ctn = c } if i == 0
271
+ ary << :before2
272
+ end,
273
+ proc { ary << :thunk },
274
+ proc do
275
+ ary << :after1
276
+ (flag = false; ctn.call) if i == 1 && flag
277
+ ary << :after2
278
+ end
279
+ )
280
+ ary << :end
281
+ i += 1
282
+ end
283
+ assert_equal([:before1, :before2, :thunk, :after1, :after2, :end, :before1, :before2, :thunk, :after1, :before2, :thunk, :after1, :after2, :end], ary)
284
+ end
285
+
286
+ def test_jump_from_after_to_thunk
287
+ ary = []
288
+ ctn = nil
289
+ flag = true
290
+ dynamicwind(
291
+ proc { ary << :before },
292
+ proc do
293
+ ary << :thunk1
294
+ callcc {|c| ctn = c }
295
+ ary << :thunk2
296
+ end,
297
+ proc do
298
+ ary << :after1
299
+ (flag = false; ctn.call) if flag
300
+ ary << :after2
301
+ end
302
+ )
303
+ assert_equal([:before, :thunk1, :thunk2, :after1, :before, :thunk2, :after1, :after2], ary)
304
+ end
305
+
306
+ def test_jump_from_after_to_thunk_2
307
+ ary = []
308
+ ctn = nil
309
+ flag = true
310
+ i = 0
311
+ while i <= 1
312
+ dynamicwind(
313
+ proc { ary << :before },
314
+ proc do
315
+ ary << :thunk1
316
+ callcc {|c| ctn = c } if i == 0
317
+ ary << :thunk2
318
+ end,
319
+ proc do
320
+ ary << :after1
321
+ (flag = false; ctn.call) if i == 1 && flag
322
+ ary << :after2
323
+ end
324
+ )
325
+ ary << :end
326
+ i += 1
327
+ end
328
+ assert_equal([:before, :thunk1, :thunk2, :after1, :after2, :end, :before, :thunk1, :thunk2, :after1, :before, :thunk2, :after1, :after2, :end], ary)
329
+ end
330
+
331
+ def test_jump_from_after_to_after
332
+ ary = []
333
+ ctn = nil
334
+ i = 0
335
+ while i <= 1
336
+ dynamicwind(
337
+ proc { ary << :before },
338
+ proc { ary << :thunk },
339
+ proc do
340
+ ary << :after1
341
+ ctn.call if ctn
342
+ ary << :after2
343
+ callcc {|c| ctn = c }
344
+ ary << :after3
345
+ end
346
+ )
347
+ ary << :end
348
+ i += 1
349
+ end
350
+ assert_equal([:before, :thunk, :after1, :after2, :after3, :end, :before, :thunk, :after1, :after3, :end], ary)
351
+ end
352
+
96
353
  def test_raise
97
354
  ary = []
98
355
  assert_raise(RuntimeError) do
@@ -185,4 +442,77 @@ class TestDynamicWind < Test::Unit::TestCase
185
442
  (flag = false; c2.call) if flag
186
443
  assert_equal([:before1, :before2, :thunk1, :after2, :after1, :end, :before1, :before2, :thunk2, :after2, :after1, :end], ary)
187
444
  end
445
+
446
+ def test_raise_in_before
447
+ ary = []
448
+ ctn = nil
449
+ flag = true
450
+ begin
451
+ dynamicwind(
452
+ proc do
453
+ ary << :before
454
+ raise if ctn
455
+ end,
456
+ proc do
457
+ ary << :thunk1
458
+ callcc {|c| ctn = c }
459
+ ary << :thunk2
460
+ end,
461
+ proc { ary << :after }
462
+ )
463
+ ary << :normal
464
+ rescue
465
+ ary << :exception
466
+ end
467
+ ary << :end
468
+ assert_nothing_raised { flag = false; ctn.call } if flag
469
+ assert_equal([:before, :thunk1, :thunk2, :after, :normal, :end, :before, :exception, :end], ary)
470
+ end
471
+
472
+ def test_raise_in_after
473
+ ary = []
474
+ ctn = nil
475
+ assert_nothing_raised do
476
+ dynamicwind(
477
+ proc { ary << :before1 },
478
+ proc do
479
+ ary << :thunk1
480
+ callcc {|c| ctn = c }
481
+ ary << :thunk2
482
+ end,
483
+ proc { ary << :after1 }
484
+ )
485
+ end
486
+ ary << :between
487
+ begin
488
+ dynamicwind(
489
+ proc { ary << :before2 },
490
+ proc do
491
+ ary << :thunk3
492
+ assert_nothing_raised { ctn.call }
493
+ end,
494
+ proc { ary << :after2; raise }
495
+ )
496
+ rescue
497
+ ary << :exception
498
+ end
499
+ ary << :end
500
+ assert_equal([:before1, :thunk1, :thunk2, :after1, :between, :before2, :thunk3, :after2, :exception, :end], ary)
501
+ end
502
+
503
+ def test_callcc_in_thunk
504
+ ary = []
505
+ dynamicwind(
506
+ proc { ary << :before },
507
+ proc do
508
+ callcc do |c|
509
+ ary << :thunk1
510
+ c.call
511
+ ary << :thunk2
512
+ end
513
+ end,
514
+ proc { ary << :after }
515
+ )
516
+ assert_equal([:before, :thunk1, :after], ary)
517
+ end
188
518
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mame-dynamicwind
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yusuke Endoh
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-20 00:00:00 -08:00
12
+ date: 2008-11-21 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency