Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions ruby/Limit use of conditional modifiers to short, simple cases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# 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
```

## References

- You can see further discussion of this guideline here: [#738](https://github.com/thoughtbot/guides/pull/738)
6 changes: 5 additions & 1 deletion ruby/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

[Sample 1](sample_1.rb) [Sample 2](sample_2.rb)

> [!TIP]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This renders as
image

> Click on the linked pull request, commit, or the guideline itself to read more
> detailed explanations with examples and reasoning behind these recommendations.

- [Use an opinionated set of rules for Rubocop](./Use an opinionated set of rules for Rubocop.md)
- Avoid conditional modifiers (lines that end with conditionals). [36491dbb9]
- [Limit use of conditional modifiers to short, simple cases](./Limit use of conditional modifiers to short, simple cases.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`
Expand Down