Project

General

Profile

Actions

Bug #17105

closed

A single `return` can return to two different places in a proc inside a lambda inside a method

Added by Eregon (Benoit Daloze) over 3 years ago. Updated about 3 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:99499]

Description

A single return in the source code might return to 2 different lexical places.
That seems wrong to me, as AFAIK all other control flow language constructs always jump to a single place.

def m(call_proc)
  r = -> {
    # This single return in the source might exit the lambda or the method!
    proc = Proc.new { return :return }

    if call_proc
      proc.call
      :after_in_lambda
    else
      proc
    end
  }.call # returns here if call_proc

  if call_proc
    [:after_in_method, r]
  else
    r.call
    :never_reached
  end
end


p m(true)  # => [:after_in_method, :return]
p m(false) # :return

We're trying to figure out the semantics of return inside a proc in
https://github.com/oracle/truffleruby/issues/1488#issuecomment-669185675
and this behavior doesn't seem to make much sense.

@headius (Charles Nutter) also seems to agree:

I would consider that behavior to be incorrect; once the proc has escaped from the lambda, its return target is no longer valid. It should not return to a different place.
https://github.com/jruby/jruby/issues/6350#issuecomment-669603740

So:

  • is this behavior intentional? or is it a bug?
  • what are actually the semantics of return inside a proc?

The semantics seem incredibly complicated to a point developers have no idea where return actually goes.
Also it must get even more complicated if one defines a lambda method as the block in lambda { return } is then non-deterministically a proc or lambda.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0