Ruby Coder
Ruby 3.x Modern Syntax
Use hash shorthand when keys match variable names:
age = 49 name = "David" user = { name:, age: }
For general naming conventions, semantic methods, and enumerable patterns, see references/ruby-style-conventions.md .
Sandi Metz's 4 Rules for Developers
These rules enforce strict limits to maintain code quality. Breaking them requires explicit justification.
Rule 1: Classes Can Be No Longer Than 100 Lines
Limit: Maximum 100 lines of code per class
Check: When a class exceeds this limit, extract secondary concerns to new classes
When exceeding 100 lines, extract secondary concerns:
class UserProfilePresenter # Presentation logic class UserProfileValidator # Validation logic class UserProfileNotifier # Notification logic
Exceptions: Valid Single Responsibility Principle (SRP) justification required
Rule 2: Methods Can Be No Longer Than 5 Lines
Limit: Maximum 5 lines per method. Each if/else branch counts as lines.
Good - 5 lines or fewer
def process_order validate_order calculate_totals apply_discounts finalize_payment end
Avoid - extract when too long
def process_order return unless items.any? return unless valid_address? self.subtotal = items.sum(&:price) self.tax = subtotal * tax_rate self.total = subtotal + tax charge_customer send_confirmation end
Exceptions: Pair approval required (Rule 0: break rules with agreement)
Rule 3: Pass No More Than 4 Parameters
Limit: Maximum 4 parameters per method. Use parameter objects or hashes when more data is needed.
Parameter object when data is related
def create_post(post_params) Post.create(user: post_params.user, title: post_params.title, content: post_params.content) end
Exceptions: Rails view helpers like link_to or form_for are exempt
Rule 4: Controllers May Instantiate Only One Object
Limit: Controllers should instantiate only one object; other objects come through that via facade pattern.
Good - single object via facade
class DashboardController < ApplicationController def show @dashboard = DashboardFacade.new(current_user) end end
Avoid - multiple instance variables
class DashboardController < ApplicationController def show @user = current_user @posts = @user.posts.recent @notifications = @user.notifications.unread end end
-
Prefix unused instance variables with underscore: @_calculation
-
Avoid direct collaborator access in views: @user.profile.avatar -> use facade method
Code Quality Standards
Thread Safety
Use Mutex for shared mutable state:
class Configuration @instance_mutex = Mutex.new
def self.instance return @instance if @instance @instance_mutex.synchronize { @instance ||= new } end end
Idempotent Operations
Design operations to be safely repeatable:
def activate_user return if user.active? user.update(active: true) send_activation_email unless email_sent? end
Refactoring Triggers
Extract classes when:
-
Class exceeds 100 lines (Sandi Metz Rule 1)
-
Class has multiple responsibilities
-
Class name contains "And" or "Or"
Extract methods when:
-
Method exceeds 5 lines (Sandi Metz Rule 2)
-
Conditional logic is complex
-
Code has nested loops or conditionals
-
Comments explain what code does (code should be self-explanatory)
Use parameter objects when:
-
Methods require more than 4 parameters (Sandi Metz Rule 3)
-
Related parameters are always passed together
-
Parameter list is growing over time
Create facades when:
-
Controllers need multiple objects (Sandi Metz Rule 4)
-
Views access nested collaborators
-
Complex data aggregation is needed
When to Break Rules
Sandi Metz's "Rule 0": Break any of the 4 rules only with pair approval or clear justification.
Rule Valid Exception
100 lines Clear SRP justification required
5 lines Complex but irreducible algorithms
4 params Rails view helpers exempt
1 object Simple views without facades
Document all exceptions with clear reasoning in code comments.
References
-
references/sandi-metz.md
-
Code smells, refactoring, testing principles
-
references/ruby-tips.md
-
Type conversion, hash patterns, proc composition, refinements
-
references/ruby-style-conventions.md
-
Naming, semantic methods, enumerables, composition