-
-
Notifications
You must be signed in to change notification settings - Fork 925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#each's return takes precendence over inner block's return with a lambda #3143
Comments
Works in 1.7, does not work in 9k HEAD. |
A workaround for you until we fix this: use "break" or "next" instead of "return". Break returns from the method receiving the block (bar) and next returns from the block itself (allowing the lambda to finish normally). I would guess we're not being strict enough about non-local returns that pass through a containing lambda. |
Output on 9k:
|
The problem is actually that the lambda (->) is capturing the return. As a result, each's return value is returned from the bar method. It passes on MRI and JRuby 1.7 because the assert never fires. The return bubbles all the way out of the test method, as it should. Simplest repro I can come up with: def foo
->{ yield }.call
return 1
end
def bar
foo { return 2 }
end
p bar |
I think clearly speccing this behavior will help fix this
If this is indeed the right thing, then lexical scoping checks in IRRuntimeHelpers while the return is bubbling might work. Will require twidding some things in there (not sure if the IRReturnJump object needs more state). |
I have a fix locally. I think we've determined the logic is that return always goes to the nearest return-capturing lexical enclosure. The fix makes the original case pass along with every other case we've formulated, and appears to pass tests. I'll push momentarily. |
@subbuss I'd appreciate your review if you get a chance! |
Seems reasonable to me. |
Awesome, thanks for the quick fix! ❤️ |
Hello,
There's a behavioral difference between JRuby and MRI when calling
#each
. If a lambda with areturn
statement is called inside#each
, the result of the latter will be returned rather than the lambda's one:Have a nice day!
The text was updated successfully, but these errors were encountered: