Skip to content

Commit

Permalink
Add specs for behavior of return in lambda
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Phoenix committed Nov 12, 2009
1 parent f319184 commit e614007
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
20 changes: 20 additions & 0 deletions spec/frozen/core/kernel/fixtures/classes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,26 @@ class Child < Parent
class Grandchild < Child
undef_method :parent_mixin_method
end

# for testing lambda
class Lambda
def outer(meth)
inner(meth)
end

def mp(&b); b; end

def inner(meth)
b = mp { return :good }

pr = send(meth) { |x| x.call }

pr.call(b)

# We shouldn't be here, b should have unwinded through
return :bad
end
end
end

class EvalSpecs
Expand Down
4 changes: 4 additions & 0 deletions spec/frozen/core/kernel/shared/lambda.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ def test
test
@reached_end_of_method.should be_true
end

it "allows long returns to flow through it" do
KernelSpecs::Lambda.new.outer(@method).should == :good
end
end
40 changes: 40 additions & 0 deletions spec/frozen/language/fixtures/return.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,44 @@ def enclosing_method
ScratchPad.record :after_invoke2
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
end
10 changes: 10 additions & 0 deletions spec/frozen/language/return_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,14 @@ def f
f.should be_true
end
end

describe "within define_method" do
it "goes through the method via a closure" do
ReturnSpecs::ThroughDefineMethod.new.outer.should == :good
end

it "stops at the method when the return is used directly" do
ReturnSpecs::DefineMethod.new.outer.should == :good
end
end
end

0 comments on commit e614007

Please sign in to comment.