Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get the return value inside 'ensure' in Ruby?

Tags:

ruby

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)?

like image 344
daremkd Avatar asked Oct 13 '14 23:10

daremkd


People also ask

How do you return a value from a method in Ruby?

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.

Does Ruby have implicit return?

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.

What does return in Ruby do?

Explicit return Ruby provides a keyword that allows the developer to explicitly stop the execution flow of a method and return a specific value.


2 Answers

Assign a Variable

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"

Early Returns Work the Same

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
like image 57
Todd A. Jacobs Avatar answered Sep 23 '22 17:09

Todd A. Jacobs


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
like image 30
moonfly Avatar answered Sep 23 '22 17:09

moonfly