def some_method
puts 'in method'
return 'I am a return value'
ensure
puts 'will print at the end'
# Can I somehow get the return value of some_method here?
end
Is there some (possibly meta-programming) principle/way to get the return value of a method inside the "ensure" clause which is a part of the method definition (which we all know executes no matter what)?
Ruby methods ALWAYS return the evaluated result of the last line of the expression unless an explicit return comes before it. If you wanted to explicitly return a value you can use the return keyword.
Ruby has implicit returns. This means that if a return is the last expression in a path of execution, there's no need for the return keyword. Worth noting is that return 's default argument is nil , which is a falsey value.
Explicit return Ruby provides a keyword that allows the developer to explicitly stop the execution flow of a method and return a specific value.
Just make your return value a variable. You can use the variable inside your ensure statement, but the return value for the method will be the last statement evaluated in the non-exceptional part of the method. For example:
def some_method
puts 'in method'
value = 'I am a return value'
ensure
puts 'will print at the end'
puts value
true
end
some_method
#=> "I am a return value"
Note that the technique above works even if you return early, since the value passed to the return keyword is still the last non-exceptional expression evaluated. For example, the following method should never return false:
def return_true
return value = true
false
ensure
puts value
false
end
return_true
#=> true
Why do you need this in ensure
? If the main part of the method completed w/o exception the return value of that part will be returned from the method (unless you do return
in ensure
). If exception happens, the return
in your main part is not calculated at all.
Of course you can always use the following (very ugly IMO) code. But please don't do that. A better idea is to leave only the resource-cleanup code in the ensure block.
def some_method
finished = false
begin
puts 'in method'
result = 'I am a return value'
finished = true
ensure
puts 'will print at the end'
# Do whatever is needed for cleanup
if finished
# Here result is defined, you can manipulate it if needed
return result
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With