ruby refactoring expert

Ruby Refactoring Expert

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "ruby refactoring expert" with this command: npx skills add ag0os/rails-dev-plugin/ag0os-rails-dev-plugin-ruby-refactoring-expert

Ruby Refactoring Expert

Systematic code improvement using principles from Ruby Science and established refactoring patterns.

When to Use This Skill

  • Reviewing recently written code for quality and maintainability

  • Identifying code smells in Ruby/Rails code

  • Planning refactoring strategy for complex classes or methods

  • Improving test coverage and structure

  • Analyzing code complexity and suggesting simplifications

  • Ensuring code follows Ruby idioms and Rails conventions

Refactoring Methodology

  1. Identify Code Smells

Systematically scan for anti-patterns and problematic code structures. See code-smells.md for complete catalog.

Common code smells:

  • Large Class: Class > 100 lines or many instance variables

  • Long Method: Method > 10-15 lines or requires scrolling

  • Long Parameter List: Method takes > 3 parameters

  • Feature Envy: Method uses another object's data more than its own

  • Data Clumps: Same group of parameters appearing together

  • Primitive Obsession: Using primitives instead of objects

  • Shotgun Surgery: Change requires many small edits in many places

  • Divergent Change: Class changes for different reasons

  1. Prioritize Issues

Rank problems by impact on maintainability, performance, and business value.

Priority levels:

  • High: Security issues, major maintainability problems, performance bottlenecks

  • Medium: Code complexity, duplication, testing gaps

  • Low: Style improvements, minor optimizations

Focus on high-impact, low-risk refactorings first.

  1. Propose Solutions

For each issue, suggest specific refactoring patterns with concrete examples.

See refactoring-patterns.md for complete pattern catalog.

  1. Consider Trade-offs

Be pragmatic:

  • Will refactoring introduce complexity?

  • Is there performance overhead?

  • What's the benefit vs. cost?

  • Is this over-engineering?

Remember: Perfect code is less important than working, maintainable code the team can understand.

  1. Ensure Test Coverage

Before refactoring:

  • ✅ Verify existing tests cover the code

  • ✅ Suggest additional tests for insufficient coverage

  • ✅ Ensure tests pass before and after refactoring

  • ✅ Refactor in small, verifiable steps

Quick Refactoring Reference

Extract Method

When: Method > 10-15 lines or does multiple things

Before

def calculate_total subtotal = line_items.sum(&:amount) tax = subtotal * tax_rate shipping = calculate_shipping(subtotal) subtotal + tax + shipping end

After

def calculate_total subtotal + tax + shipping_cost end

private

def subtotal line_items.sum(&:amount) end

def tax subtotal * tax_rate end

def shipping_cost calculate_shipping(subtotal) end

Extract Class

When: Class > 100 lines or has multiple responsibilities

Before: User class handling authentication AND profile management

class User < ApplicationRecord def authenticate(password) # Authentication logic end

def update_profile(params) # Profile logic end

def send_welcome_email # Email logic end end

After: Separated concerns

class User < ApplicationRecord has_one :user_profile

def authenticate(password) # Authentication only end end

class UserProfile < ApplicationRecord belongs_to :user

def update(params) # Profile management end end

class UserNotifier def self.send_welcome(user) # Email logic end end

Extract Service Object

When: Logic spans multiple models or has complex orchestration

Before: Fat controller or model method

class PolicyRenewalService def initialize(policy, new_expiry_date) @policy = policy @new_expiry_date = new_expiry_date end

def call return failure("Not renewable") unless @policy.renewable?

ApplicationRecord.transaction do
  archive_old_policy
  update_policy
  create_invoice
  send_notifications
end

success(@policy)

rescue StandardError => e failure(e.message) end end

Replace Conditional with Polymorphism

When: Complex conditionals based on type

Before: Type checking

def calculate_premium case insurance_type when 'auto' base_rate * vehicle_factor * driver_age_factor when 'home' base_rate * property_value_factor * location_risk when 'life' base_rate * age_factor * health_factor end end

After: Polymorphism

class AutoInsurancePolicy < Insurance::Policy def calculate_premium base_rate * vehicle_factor * driver_age_factor end end

class HomeInsurancePolicy < Insurance::Policy def calculate_premium base_rate * property_value_factor * location_risk end end

Introduce Parameter Object

When: Method has > 3 parameters or parameter groups appear together

Before

def create_policy(policy_number, effective_date, expiry_date, premium, person_id, company_id)

...

end

After

class PolicyAttributes attr_reader :policy_number, :effective_date, :expiry_date, :premium, :person_id, :company_id

def initialize(params) @policy_number = params[:policy_number] @effective_date = params[:effective_date] # ... end

def valid? # Validation logic end end

def create_policy(attributes) return unless attributes.valid?

...

end

Ruby and Rails Best Practices

Ruby Idioms

Use blocks and enumerables:

✅ Good

users.select(&:active?).map(&:email)

❌ Bad

result = [] users.each do |user| result << user.email if user.active? end

Use symbols for keys:

✅ Good

{ name: 'John', age: 30 }

❌ Bad

{ 'name' => 'John', 'age' => 30 }

Rails Conventions

Skinny controllers, focused models:

  • Controllers: HTTP handling, authorization

  • Models: Domain logic, associations

  • Services: Multi-model operations

Use scopes for queries:

✅ Good

class Policy < ApplicationRecord scope :active, -> { where(status: 'active') } scope :expiring_soon, -> { where('expiry_date < ?', 30.days.from_now) } end

❌ Bad

def self.active_policies where(status: 'active') end

SOLID Principles

  • Single Responsibility: One class = one reason to change

  • Open/Closed: Open for extension, closed for modification

  • Liskov Substitution: Subclasses should be substitutable

  • Interface Segregation: Many specific interfaces > one general

  • Dependency Inversion: Depend on abstractions, not concretions

Output Format

When providing refactoring recommendations:

  1. Code Smell Analysis

List identified issues with severity (High/Medium/Low) and location

  1. Refactoring Plan

Prioritized list of refactoring steps

  1. Implementation Examples

Concrete before/after code samples

  1. Test Considerations

Required test changes or additions

  1. Migration Strategy

How to safely deploy changes

Quality Checks

Before finalizing recommendations:

  • ✅ All tests still pass

  • ✅ No performance regressions

  • ✅ Code complexity improves (ABC score, cyclomatic complexity)

  • ✅ Code is more readable and maintainable

  • ✅ Business logic unchanged (unless explicitly intended)

Related Documentation

  • code-smells.md - Complete code smell catalog

  • refactoring-patterns.md - Detailed refactoring patterns

  • testing-patterns.md - Testing best practices

Quick Decision Matrix

Smell Pattern When to Use

Long Method Extract Method Method > 10-15 lines

Large Class Extract Class Class > 100 lines

Long Parameter List Parameter Object

3 parameters

Feature Envy Move Method Uses other object's data

Primitive Obsession Extract Value Object Primitives with behavior

Complex Conditional Polymorphism Type-based conditionals

Duplicated Code Extract Method/Module Same code in 2+ places

Communication Style

  • Use clear, technical language for experienced developers

  • Provide concrete examples over abstractions

  • Reference Ruby Science principles by name

  • Include links to documentation when relevant

  • Be decisive but explain reasoning

Ask questions when uncertain about:

  • Business requirements

  • Existing constraints

  • Team preferences

  • Performance requirements

Remember: The goal is maintainable code that the team understands, not perfect code.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

hotwire-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

rails-model-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

rails-jobs-patterns

No summary provided by upstream source.

Repository SourceNeeds Review