Style, Idioms and Best Practices
54.1 Idiomatic Ruby
# ✅ Idiomatic # ❌ Non-idiomatic
names.each { |n| puts n } # for n in names do puts n end
return unless valid? # if !valid? then return end
items.empty? # items.length == 0
user&.name # user && user.name
count ||= 0 # count = 0 if count.nil?
"Hello, #{name}" # "Hello, " + name
%w[a b c] # ["a", "b", "c"]
nums.map(&:to_s) # nums.map { |n| n.to_s }
hash.fetch(:key) # hash[:key] || raise(...)
File.open(path) { |f| f.read } / File.read(path) # f = File.open(path); ...; f.close
def admin? = role == :admin # def is_admin; return role == :admin; end
items.each_with_object({}) { |i, h| h[i.id] = i } # h = {}; items.each { |i| h[i.id] = i }; h
raise ArgumentError, "msg" # raise ArgumentError.new("msg")54.2 Best Practices Checklist
✅ Follow the Ruby Style Guide (rubystyle.guide). Enforce it with RuboCop or Standard.
✅ Two-space indentation, snake_case methods, CamelCase classes, ?/! naming conventions.
✅ Small methods and classes (single responsibility). Prefer composition and modules over deep inheritance.
✅ Use # frozen_string_literal: true. Use Data/freeze for value objects.
✅ Prefer fetch for required keys, keyword arguments for clarity, guard clauses for early exits.
✅ Rescue specific exceptions. Define custom error hierarchies.
✅ Write tests (Minitest/RSpec) and measure coverage. Use CI.
✅ Use Bundler and commit Gemfile.lock for apps. Keep dependencies updated and audited.
✅ Document public APIs (YARD). Add RBS/Sorbet types for larger codebases.
✅ Prefer public_send over send. Pair method_missing with respond_to_missing?.
❌ Avoid global variables, @@class_variables, and monkey patching core classes (use refinements).
❌ Don't rescue Exception. Don't use eval with external input.
❌ Don't use for loops or and/or for boolean logic (only for control flow).
❌ Avoid "clever" metaprogramming when plain code is clearer.
54.3 Design Principles in Ruby
SOLID, DRY, KISS, YAGNI, the Law of Demeter ("tell, don't ask").
Patterns in Ruby: Service Objects, Form Objects, Query Objects, Decorators/Presenters (SimpleDelegator), Value Objects (Data), Null Object, Observer (callbacks/ActiveSupport::Notifications), Strategy (duck-typed objects or lambdas), Builder (DSL blocks), Adapter, Command, Repository.
Recommended reading: *Practical Object-Oriented Design* (Sandi Metz), the *99 Bottles of OOP* book, *Refactoring: Ruby Edition*.