From 0f20d4999d519d277dd05777d67672c6dda8e702 Mon Sep 17 00:00:00 2001 From: Matheus Richard Date: Fri, 28 Mar 2025 12:00:54 -0300 Subject: [PATCH] Limit use of conditional modifiers to short, simple cases. Co-authored-by: Richard Newman --- ruby/README.md | 7 ++- ruby/conditional_modifiers.md | 86 +++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 ruby/conditional_modifiers.md diff --git a/ruby/README.md b/ruby/README.md index 687d6e7b..068f22b9 100644 --- a/ruby/README.md +++ b/ruby/README.md @@ -2,8 +2,13 @@ [Sample 1](sample_1.rb) [Sample 2](sample_2.rb) +> **TIP** +> +> Click on the linked pull request, commit, or the guideline itself to read more +> detailed explanations with examples and reasoning behind these recommendations. + - Use [standard] -- Avoid conditional modifiers (lines that end with conditionals). [36491dbb9] +- [Limit use of conditional modifiers to short, simple cases.](./conditional_modifiers.md) - Avoid multiple assignments per line (`one, two = 1, 2`). [#109] - Avoid organizational comments (`# Validations`). [#63] - Avoid ternary operators (`boolean ? true : false`). Use multi-line `if` diff --git a/ruby/conditional_modifiers.md b/ruby/conditional_modifiers.md new file mode 100644 index 00000000..3a364826 --- /dev/null +++ b/ruby/conditional_modifiers.md @@ -0,0 +1,86 @@ +# Limit use of conditional modifiers to short, simple cases + +Conditional modifiers (i.e., `if` or `unless` at the end of a line) can be +surprising when they appear on long or complex lines. The reader might not see +them while scanning the code. + +So, prefer to use them only for short, simple cases. For example: + +```ruby +do_later if async? +``` + +The example above can read more naturally than: + +```rb +if async? + do_later +end +``` + +## Complex conditions + +However, if the line is too long (around 80 characters) or complex (e.g., an +`if` with multiple conditions like `if a && b`) prefer the multi-line form: + +```ruby +# Avoid +block_access! if signed_in? && !current_user.active? + +# Prefer +if signed_in? && !current_user.active? + block_access! +end +``` + +There might be cases where the conditional modifier work well with multiple +conditions, so use your best judgment. + +## An opportunity to refactor + +If the conditions are related, consider extracting a method that groups them. +This might allow you to use the conditional modifier form again. + +```ruby +def inactive_user? + signed_in? && !current_user.active? +end + +block_access! if inactive_user? +``` + +## Conditional modifiers feel informal + +The modifier form of conditionals can feel more casual than the multi-line form. +Conversely, the multi-line form _draws attention_ to the conditional and the +code that follows it. Use this to your advantage when you want to emphasize the +conditional and the code that follows it. + +```rb +# Avoid +def action + return destroy_all if really? + + do_nothing +end + +# Prefer +def action + if really? + destroy_all + else + do_nothing + end +end +``` + +You can also refactor the code so the less destructive action uses a conditional +modifier, which pairs well with the informal feel of the modifier form: + +```rb +def action + return do_nothing if chill? + + destroy_all +end +```