I am new to ruby and start learning ruby, and i came to this proc return concept where i completely confused how the proc is returning differently.
I am attaching my code here for the reference. I did google search too but couldn't get my answer if anyone could help please.
def call_proc
puts "Before proc"
my_proc = Proc.new { return 2 }
my_proc.call
puts "After proc"
end
def proc_call
def inside_call
my_proc = Proc.new {return 4}
end
proc = inside_call
proc.all
end
CodePudding user response:
I can't see the difference in those 2 pieces of code ... However it all appears to be working the way it is supposed to. Proc
s work the same way no matter how you call them.
see: https://www.codecademy.com/learn/learn-ruby/modules/learn-ruby-blocks-procs-and-lambdas-u/cheatsheet and https://www.rubyguides.com/2016/02/ruby-procs-and-lambdas/#Lambdas_vs_Procs
Your code (and my output):
def call_proc
my_proc = Proc.new { return 2 }
puts "Before proc"
my_proc.call
puts "After proc"
end
def proc_call
def inside_call
my_proc = Proc.new {return 4}
end
proc = Proc.new {return 4}
puts "Before proc"
proc.call
puts "After proc"
end
Output:
2.7.2 :112 > call_proc
Before proc
=> 2
2.7.2 :113 > proc_call
Before proc
=> 4
2.7.2 :114 >
In comparison, where you want to carry on after your Proc
, you might be better off performing a Lambda
:
def call_lambda
my_lambda = -> { return 17 }
puts "Before lambda"
puts my_lambda.call
puts "After lambda"
end
(note the puts
before the call, and the return value of nil
)
2.7.2 :122 > call_lambda
Before lambda
17
After lambda
=> nil
CodePudding user response:
First of all, there are no nested methods in Ruby. The 2nd part of your code is equivalent to:
def inside_call
Proc.new { return 4 }
end
def proc_call
proc = inside_call
proc.call
end
Calling proc_call
(still) results in a LocalJumpError
. This is because return
within a proc will always attempt to return from the method the proc was defined in (i.e. from inside_call
). From the docs:
- In non-lambda procs,
return
means exit from embracing method (and will throwLocalJumpError
if invoked outside the method);