Ruby Logo

Idiomatic Ruby

Write expressive, intention-revealing Ruby by embracing enumerable pipelines, guard clauses, and Ruby idioms.

Home Ruby Idiomatic Ruby

Writing Idiomatic Ruby

Idiomatic Ruby leans on expressiveness, small methods, and the rich Enumerable toolkit. When we ship features in RubyDev, we reward readers with code that reads like prose and embraces Rubyisms such as guard clauses, symbol-to-proc, predicate methods, and implicit returns.

Idioms That Keep Code Expressive

Predicate Methods

Append `?` for boolean return values (`published?`, `archived?`) and `!` for bang variants (`save!`) to communicate intent instantly.

Symbol-to-Proc

Replace `{ |user| user.id }` with `&:id` for concise enumerations and pass method names directly to iterators.

Truthiness

Only `nil` and `false` are falsy. Leverage that to simplify conditionals—`return if errors.present?` is often clearer than comparing to `[]`.

Enumerable Pipelines Over Imperative Loops

# Before: imperative loop
totals = [] orders.each do |order| next unless order.subtotal.positive? totals << order.subtotal * 1.15 end valid_totals = totals.sort.reverse.first(3)
# After: expressive pipeline
valid_totals = orders .select(&:billable?) .map { |order| order.subtotal * 1.15 } .sort .reverse .first(3)

Pipelines make transformation steps visible and chainable. Use `tap`, `yield_self`, and `then` when you need to observe or transform intermediate values without mutating state.

Lazy enumerables

Use `lazy` when mapping huge collections or streaming data to avoid eager intermediate arrays.

Hash transforms

`transform_values`, `transform_keys`, and `slice` provide descriptive alternatives to manual loops.

Nil, Exceptions, and Safe Defaults

Embrace `&.` (safe navigation), `fetch` with defaults, and domain-specific Null Objects to prevent nil-check explosions.

class NullLesson
def title = 'Coming soon'
def published? = false
def duration_minutes = 5
end

lesson = course.lessons.detect(&:published?) || NullLesson.new
puts lesson.title #=> "Coming soon" (no nil errors)

Practice Prompts

  1. Refactor an imperative loop from the codebase into an Enumerable chain with `map`, `select`, and `sum`.
  2. Replace nested conditionals with guard clauses in a service object, then annotate the change in your PR description.
  3. Create a null-object implementation for an optional dependency and document when to reach for it.

Quick Navigation

Related Topics

Video Tutorial

Watch and learn idiomatic ruby

Pro Tip: After reading through the content above, watch this video to reinforce your understanding and see the concepts in action!