Reputation: 323
Can someone explain the behavior of the following
def iterate
return yield
return "end of iterate"
end
def test_iterate
assert_equal( "end of iterate", iterate { return "end of block" } )
assert_equal( "end of block", iterate { "end of block" } )
end
I understand that Procs ( Which is what blocks are ) should return within the scope they are called. ( Unlike lambdas ) With this in mind, shouldn't both calls in the tests return "end of block"?
This test passes on 'ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]' ( OSX 10.6.7 )
Upvotes: 3
Views: 1058
Reputation: 29930
The return keyword returns from the lexicaly enclosing method. That is, *test_iterate*.
To return a certain value from a block in a dynamically scoped fashion, you should use the break keyword instead.
In your case:
iterate { break("end of block") }
The test will fail. because the second return statement of the iterate method will never run.
The intended semantics should be accomplished by using exceptions:
def iterate
return yield
rescue :exception
return "end of iterate"
end
def test_iterate
assert_equal( "end of iterate", iterate { raise :exception } )
assert_equal( "end of block", iterate { "end of block" } )
end
Upvotes: 4