Forum: Ruby unexpected return (LocalJumpError)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Kyung won C. (Guest)
on 2008-11-12 06:40
def a
  blk = Proc.new { return }
  blk.call
end

a                         # => It's OK

def a(blk)
  blk.call
end

blk = lambda { return }
a blk                     # => It's OK

blk = Proc.new { return }
a blk                     # => unexpected return (LocalJumpError)


############
# Help Me^^
############
Mike G. (Guest)
on 2008-11-12 08:26
Kyung won Cheon wrote:
> def a
>   blk = Proc.new { return }
>   blk.call
> end
>
> a                         # => It's OK
>
> def a(blk)
>   blk.call
> end
>
> blk = lambda { return }
> a blk                     # => It's OK
>
> blk = Proc.new { return }
> a blk                     # => unexpected return (LocalJumpError)

% ruby -e 'return'
-e:1: unexpected return (LocalJumpError)

That is what you are seeing.  'return' interrupts a method, but there is
no method at the top-level scope.

def a(blk)
  blk.call
end

def main
  blk = Proc.new { return }
  p "before"
  a blk
  p "after"  # never gets here
end

main  # => "before"
Brian C. (Guest)
on 2008-11-12 10:55
For the differences between lambda and Proc, including a lot of gory
detail, see
http://innig.net/software/ruby/closures-in-ruby.rb
Robert D. (Guest)
on 2008-11-12 12:10
(Received via mailing list)
On Wed, Nov 12, 2008 at 9:52 AM, Brian C. <removed_email_address@domain.invalid>
wrote:
> For the differences between lambda and Proc, including a lot of gory
> detail, see
> http://innig.net/software/ruby/closures-in-ruby.rb
or better dont,
All you need to know is that lambda and Proc::new behave as they are
designed to behave, therefore the behavior you encountered is not a
bug but a feature as surprising as that comes to most of us ;). IIRC
this will change in 1.9
To better understand what really happens just run this code:
def a blk
  b blk
  puts :in_a
end

def b blk
  c blk
  puts :in_b
end

def c blk
  blk.call
  puts :in_c
end

def main

  #a lambda{ puts :in_lambda; return; puts :nonsense}
  #a Proc::new{ puts :in_proc; return; puts :nonsense}
  puts :in_main
end

 --
> Posted via http://www.ruby-forum.com/.
>
>



--
C'est véritablement utile puisque c'est joli.

Antoine de Saint Exupéry
Brian C. (Guest)
on 2008-11-12 19:15
Robert D. wrote:
> IIRC this will change in 1.9

In what way?

proc is now an alias for Proc.new instead of lambda. But what other
changes are in the pipeline?

BTW I agree that this is a feature, not a bug. But it's not obvious to
the newcomer that there are two, rather different, closure-like objects:

- lambda is standalone. A 'return' returns from the lambda.

- Proc.new / block is created within the context of a method. A 'return'
  returns from that method. If the method has already terminated, then
  'return' makes no sense and causes an error.

The first is what Lisp programmers expect. The second is what makes it
possible to write

   def calculate_something(foo)
     foo.each do |params|
       ...
       return val if cond
     end
   end
This topic is locked and can not be replied to.