Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

return early vs if in ruby code

I see two styles of writing the same thing:

def find_nest(animal)
  return unless animal.bird?
  GPS.find_nest(animal.do_crazy_stuff)
end

vs

def find_nest(animal)
  if animal.bird?
     GPS.find_nest(animal.do_crazy_stuff)
  end
end

Which one is more correct/preferable/following-best-practises? Or it does not matter?

like image 758
Filip Bartuzi Avatar asked Jun 17 '16 11:06

Filip Bartuzi


People also ask

What does an if statement return in Ruby?

If your if statement doesn't result in any code being run, it returns nil, Otherwise, it returns the value of the code that was run.

Are Early returns any good?

One of the reasons that you could consider using early returns is that it keeps your code visually flatter. There is no need for extra indentation that you would have had if you went for the alternative route that uses a wrapping if-statement. This makes code more readable.

Do you need return statements 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.

What does the return function do in Ruby?

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

As per Ruby style guide,

Prefer a guard clause when you can assert invalid data. A guard clause is a conditional statement at the top of a function that bails out as soon as it can.

# bad
def compute_thing(thing)
  if thing[:foo]
    update_with_bar(thing)
    if thing[:foo][:bar]
      partial_compute(thing)
    else
      re_compute(thing)
    end
  end
end

# good
def compute_thing(thing)
  return unless thing[:foo]
  update_with_bar(thing[:foo])
  return re_compute(thing) unless thing[:foo][:bar]
  partial_compute(thing)
end
like image 162
Wand Maker Avatar answered Oct 14 '22 12:10

Wand Maker


It is obviously a matter of personal preference. But I prefer the early return. Not only does it make code "flatter" and easier to read, it also scales well with the number of checks. For example:

  def create_terms_of_service_notification
    return if Rails.env.test?
    return if current_user.accepted_tos?
    # imagine 5 more checks here. 
    # Now imagine them as a mess of nested ifs.

    # create the notification
  end
like image 36
Sergio Tulentsev Avatar answered Oct 14 '22 12:10

Sergio Tulentsev