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
|
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 its old value.
#
# We can therefore use val to figure out what happened.
begin
val = foo()
ensure
return val
end
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
|