ruby-style-guide icon indicating copy to clipboard operation
ruby-style-guide copied to clipboard

formatting multiline boolean expressions

Open jmanian opened this issue 6 years ago • 5 comments

How should one format multiline boolean expressions? For instance maybe each condition is a long statement and it would be too long or unreadable on a single line. Or should this be avoided altogether? If so, what's the alternative?

I couldn't find any guidance on this in the style guide. Should it be added, whatever the verdict is?

One option:

def my_predicate?
  first_long_condition ||
  second_long_condition ||
  third_long_condition ||
  last_long_condition
end

Or maybe with indentation after the first one?

def my_predicate?
  first_long_condition ||
    second_long_condition ||
    third_long_condition ||
    last_long_condition
end

Or wrap only when you hit the line limit? With or without indenting?

def my_predicate?
  first_long_condition || second_long_condition ||
    third_long_condition || last_long_condition
end

Of course you could give each condition its own predicate method, but in many cases that's overkill:

def predicate_one?
  first_long_condition
end

# and so forth ...

def my_predicate?
  predicate_one? || predicate_two? || predicate_three? || predicate_four?
end

You could evaluate them separately and assign the results, but you forfeit short-circuit evaluation:

def my_predicate?
  a = first_long_condition
  b = second_long_condition
  c = third_long_condition
  d = last_long_condition

  a || b || c || d
end

This is related to #476 but not exactly the same.

jmanian avatar Jul 20 '17 17:07 jmanian

My preference goes to

def my_predicate?
  first_long_condition \
  || second_long_condition \
  || third_long_condition \
  || last_long_condition
end

No indentation without nesting (just like elixirs |> is never indented), no mistaking the last line as the single return line.

Hampei avatar May 03 '18 09:05 Hampei

Another option would be to ignore the superfluous return rule here and type it as:

def my_predicate?
  return first_long_condition ||
         second_long_condition ||
         third_long_condition ||
         last_long_condition
end

Hampei avatar May 03 '18 09:05 Hampei

Somehow I always forget this and keep googling "multi line boolean ruby github" every time.

aesyondu avatar Aug 16 '20 04:08 aesyondu

I guess it depends.

# good - related in groups
def ready_to_rock?
  slept_well? && full? && in_good_mood? &&
    turned_furnace_off? && turned_kettle_off?
end

# good - all unrelated
def hero?
  saved_a_child? ||
    invented_perpetuum_mobile? ||
    doesnt_let_mom_down?
end

# good - all related
def tasty?
  salty? || sour? || sweet? || bitter? || umami?
end

in the first case, it seems preliminary to extract related predicates into their own methods.

pirj avatar Feb 21 '21 19:02 pirj

How do you format nested multiline boolean methods grouped with || for example ? This is what I do currently :

def my_predicate?
  (
    my_predicate_1? &&
    (
       my_predicate_2? ||
       my_predicate_3?
    )
  ) ||
  (
    my_predicate_4? &&
    my_predicate_5?
  )
end

I'm talking strictly about formatting. Saying that predicates in this case should be refactored in their own method is not very helpful.

abdelbk avatar Jul 13 '23 12:07 abdelbk