jtanadi
jtanadi

Reputation: 3

Ruby's if / else in methods

EDIT: I've received answers about refactoring to a ternary operation. While I'm aware that that's possible with all the languages below, that wasn't necessarily my intent with the original question about style. I've edited the snippets to reflect this.


I am curious if it's idiomatic or preferred to always use an else when using if/else in a method.

For example, in JS, this is stylistically acceptable (and sometimes preferred)

function jsFunc(x) {
  if (x == 0) {
    // do a bunch of stuff here
    return answer;
  }

  // do something else
  return differentAnswer;
}

and I've also seen a similar style in Python:

def py_func(x):
    if x == 0:
        # do a bunch of stuff here
        return answer
    # do something here
    return differentAnswer

but from the Ruby I've seen, it's always:

def ruby_method(x)
  if x == 0
    # do a bunch of stuff here
    answer
  else
    # do something else
    differentAnswer
  end
end

I've also gotten a comment that not using an else in Ruby seems messier. Do Rubyists prefer the explicit else? (Also curious a lot of the language is implicit.)

Upvotes: 0

Views: 2259

Answers (2)

ndnenkov
ndnenkov

Reputation: 36101

It actually depends.

Guard clause returns are actually used in Ruby quite often. They are even encouraged by the widely accepted style guide.

However, guard clauses are used in corner cases. So you have to ask yourself what are the possible values of x and how often is it actually 0?


If it's rarely 0 and it's somewhat special, the return at the start is perfectly acceptable (and encouraged).

For example, this is a perfectly serviceable (even though not optimal) implementation of factorial:

def factorial(n)
  return 1 if n.zero?

  n * factorial(n.pred)
end

Reason being that 0 is definitely a corner case.


If, on the other hand, the 'Yes' and 'No' cases are both likely and normal, this symmetry should be visually represented in the code (if - else).

For example, consider a robot deciding what to do on a traffic light:

def take_action(light)
  if light.green?
    go
  elsif light.yellow?
    prepare_to_go
  elsif light.red?
    wait
  end
end

You can write it with guard clauses, but it sounds weird. All of the possible colours are equally a "main" colour.


Either way, in this specific case there is a more concise alternative:

x.zero? ? 'Yes' : 'No' 

Upvotes: 6

Ursus
Ursus

Reputation: 30056

I think this is due to the fact that in Ruby we have implicit return and Ruby developers tend to dislike the use of return. In fact, the alternative to your snippet would be

def ruby_method(x)
  return "Yes" if x.zero?
  "No"
end

Kinda strange I think

Upvotes: 1

Related Questions