blob: 0414c356e8737bd8dc5cb4ba58a5936f9807a556 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
module ReturnSpecs
class Blocks
def yielding_method
yield
ScratchPad.record :after_yield
end
def enclosing_method
yielding_method do
ScratchPad.record :before_return
return :return_value
ScratchPad.record :after_return
end
ScratchPad.record :after_call
end
end
class NestedCalls < Blocks
def invoking_method(&b)
yielding_method(&b)
ScratchPad.record :after_invoke
end
def enclosing_method
invoking_method do
ScratchPad.record :before_return
return :return_value
ScratchPad.record :after_return
end
ScratchPad.record :after_invoke
end
end
class NestedBlocks < Blocks
def enclosing_method
yielding_method do
yielding_method do
ScratchPad.record :before_return
return :return_value
ScratchPad.record :after_return
end
ScratchPad.record :after_invoke1
end
ScratchPad.record :after_invoke2
end
end
class SavedInnerBlock
def add(&b)
@block = b
end
def outer
yield
@block.call
end
def inner
yield
end
def start
outer do
inner do
add do
ScratchPad.record :before_return
return :return_value
end
end
end
ScratchPad.record :bottom_of_start
return false
end
end
class ThroughDefineMethod
lamb = proc { |x| x.call }
define_method :foo, lamb
def mp(&b); b; end
def outer
pr = mp { return :good }
foo(pr)
return :bad
end
end
class DefineMethod
lamb = proc { return :good }
define_method :foo, lamb
def outer
val = :bad
# This is tricky, but works. If lamb properly returns, then the
# return value will go into val before we run the ensure.
#
# If lamb's return keeps unwinding incorrectly, val will still
# have it's old value.
#
# We can therefore use val to figure out what happened.
begin
val = foo()
ensure
if val != :good
return :bad
end
end
return val
end
end
class MethodWithBlock
def method1
return [2, 3].inject 0 do |a, b|
a + b
end
nil
end
def get_ary(count, &blk)
count.times.to_a do |i|
blk.call(i) if blk
end
end
def method2
return get_ary 3 do |i|
end
nil
end
end
end
|