Imported from Topline-com/code-skills (
skills/ruby-refactor/AGENTS.md). Install upstream withnpx skills add Topline-com/code-skills --skill ruby-refactor. Copyright stays with the author.
Ruby Refactoring
Version 0.1.0 Community February 2026
Note: This document is for agents and LLMs to follow when refactoring Ruby codebases. Humans may also find it useful, but guidance here is optimized for automation and consistency by AI-assisted workflows.
Abstract
Comprehensive refactoring guide for Ruby applications, designed for AI agents and LLMs. Contains 45 rules across 8 categories, prioritized by impact from critical (structure decomposition, conditional simplification) to incremental (naming and readability). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics to guide automated refactoring and code generation.
Table of Contents
- Structure & Decomposition — CRITICAL
- 1.1 Compose Methods at Single Abstraction Level — CRITICAL (reduces mixed abstraction levels from N to 1 per method)
- 1.2 Extract Class for Single Responsibility — CRITICAL (reduces class coupling by 50-80%)
- 1.3 Extract Long Methods into Focused Units — CRITICAL (reduces cognitive load by 3-5x)
- 1.4 Flatten Deep Nesting with Early Extraction — HIGH (reduces cyclomatic complexity by 40-60%)
- 1.5 Introduce Parameter Object for Long Signatures — CRITICAL (eliminates parameter coupling across call chain)
- 1.6 One Reason to Change per Class — HIGH (reduces change cascade across codebase)
- 1.7 Replace Complex Method with Method Object — HIGH (enables decomposition of tangled logic)
- Conditional Simplification — CRITICAL
- 2.1 Consolidate Duplicate Conditional Fragments — HIGH (reduces duplication by 30-50%)
- 2.2 Extract Complex Booleans into Named Predicates — CRITICAL (reduces boolean complexity from N clauses to 1 named predicate)
- 2.3 Replace case/when with Polymorphism — CRITICAL (eliminates shotgun surgery across N branches)
- 2.4 Replace Nested Conditionals with Guard Clauses — CRITICAL (reduces nesting depth by 2-4 levels)
- 2.5 Replace nil Checks with Null Object — HIGH (eliminates N nil-guard conditionals per call site)
- 2.6 Use Pattern Matching for Structural Conditions — HIGH (reduces 3-5 nested nil checks to 1 expression)
- Coupling & Dependencies — HIGH
- 3.1 Avoid Class Methods in Domain Logic — MEDIUM-HIGH (reduces test setup from global stubs to 1 constructor injection)
- 3.2 Enforce Law of Demeter with Delegation — HIGH (reduces coupling to 1 dependency per call)
- 3.3 Inject Dependencies via Constructor Defaults — HIGH (enables test isolation without monkey-patching)
- 3.4 Move Method to Resolve Feature Envy — HIGH (reduces cross-class coupling from N accessors to 1 method call)
- 3.5 Replace Mixin with Composed Object — HIGH (eliminates hidden method conflicts and unclear precedence)
- 3.6 Tell Objects What to Do, Don't Query Their State — MEDIUM-HIGH (reduces caller coupling from N state queries to 1 command)
- Ruby Idioms — HIGH
- 4.1 Always Pair method_missing with respond_to_missing? — MEDIUM-HIGH (prevents broken respond_to? and method introspection)
- 4.2 Name Boolean Methods with ? Suffix — MEDIUM-HIGH (eliminates N return-type lookups per code review)
- 4.3 Omit Explicit return for Last Expression — MEDIUM-HIGH (follows Ruby convention, reduces noise)
- 4.4 Use Keyword Arguments for Clarity — HIGH (self-documents call sites, prevents argument order bugs)
- 4.5 Use map/select/reject Over each with Accumulator — HIGH (eliminates mutable accumulator pattern)
- 4.6 Use respond_to? Over is_a? for Type Checking — HIGH (enables polymorphism without inheritance hierarchy)
- 4.7 Use yield Over block.call for Simple Blocks — MEDIUM-HIGH (avoids Proc allocation, 2-5x faster)
- Data & Value Objects — MEDIUM-HIGH
- 5.1 Encapsulate Collections Behind Domain Methods — MEDIUM-HIGH (prevents external mutation and scatters)
- 5.2 Replace Data Clumps with Grouped Objects — MEDIUM (eliminates parameter coupling across 3+ methods)
- 5.3 Replace Primitive Obsession with Value Objects — MEDIUM-HIGH (reduces scattered validation from N call sites to 1 constructor)
- 5.4 Separate Query Methods from Command Methods — MEDIUM (enables safe caching and idempotent reads)
- 5.5 Use Data.define for Immutable Value Objects — MEDIUM-HIGH (immutable by default, 10-50x faster construction than OpenStruct)
- Design Patterns — MEDIUM
- 6.1 Define Algorithm Skeleton with Template Method — MEDIUM (eliminates 60-80% duplicated algorithm code across N subclasses)
- 6.2 Extract Algorithm Variations into Strategy Objects — MEDIUM (reduces case/when branches from N to 0 in caller)
- 6.3 Implement Null Object with Full Protocol — MEDIUM (eliminates conditional nil checking across entire call chain)
- 6.4 Use Factory Method to Abstract Object Creation — MEDIUM (decouples creation from usage, enables extension)
- 6.5 Wrap Objects with Decorator for Added Behavior — MEDIUM (reduces subclass explosion from 2^N combinations to N decorators)
- Modern Ruby 3.x — MEDIUM
- 7.1 Implement deconstruct_keys for Custom Pattern Matching — MEDIUM (enables pattern matching on domain objects)
- 7.2 Use case/in for Structural Pattern Matching — MEDIUM (reduces 3-5 nested hash checks to 1 destructuring expression)
- 7.3 Use Endless Method Definition for Simple Methods — MEDIUM (reduces noise for one-liner methods)
- 7.4 Use Pattern Matching with Guard Clauses — MEDIUM (reduces nested if/case from 3-4 levels to 1 flat match)
- 7.5 Use Rightward Assignment for Pipeline Expressions — LOW-MEDIUM (reduces left-side noise in multi-step pipelines by 30-50%)
- Naming & Readability — LOW-MEDIUM
- 8.1 Rename to Eliminate Need for Comments — LOW-MEDIUM (eliminates 1 comment per renamed method or variable)
- 8.2 Spell Out Names Except Universal Abbreviations — LOW-MEDIUM (prevents ambiguity and miscommunication)
- 8.3 Use Intention-Revealing Names — LOW-MEDIUM (eliminates need for explanatory comments)
- 8.4 Use One Word per Concept Across Codebase — LOW-MEDIUM (prevents confusion between synonyms)