5 ms·
irb(main):002:0> p = Proc.new { return :to_sender } => #<Proc:0x0035a050@(irb):2> irb(main):003:0> p.call LocalJumpError: unexpected return
by fendale 18y ago
irb(main):002:0> p = Proc.new { return :to_sender }
=> #<Proc:0x0035a050@(irb):2>
irb(main):003:0> p.call
LocalJumpError: unexpected return
from (irb):2
from (irb):3
from :0
irb(main):007:0> l = lambda { return :to_sender }
=> #<Proc:0x0033b86c@(irb):7>
irb(main):008:0> l.call
=> :to_sender
I had no idea it would do that - is a 'return' statement illegal in a Proc?
- raganwald 18y agoA return statement is not illegal, however it returns from the method call where it was defined... if that method call is still valid. So this works: def valid_method_call pp = Proc.new { return :to_method_caller } pp.call end valid_method_call But this does not: ll = lambda { pp = Proc.new { return :to_lambda_caller } pp.call } ll.call If you do something like save the proc for later, you are in trouble: def temporary_method_call Proc.new { return :where_shall_i_return? } end pp = temporary_method_call pp.call Because the method call where the proc was defined no longer exists. So Ruby closes over local variable bindings, saving them for later, but not over control flow. If it did, the return keyword would end up acting like a continuation.
- ezmobius 18y agonow try this on for size. I'm sure you know how this works: > def a > yield > end => nil > a { 42 } => 42 But did you know this? > def b > Proc.new.call > end => nil > b { 42 } => 42 Proc.new without any arguments works the same as yield. tripped me out when I found this the other day.
- Andys 18y agoIts nice that we can choose how we want return to behave in a block. It doesnt make any sense that the two ways be called "lambda" and "Proc.new". Maybe you have to be Japanese to understand it?
- gommm 18y agoSo what is the point of using Proc instead of lambda then? I can't see a case where the behavior of proc is the desired behavior (although now that with the difference in my mind I might end up using it one day...)