Skip to content
Skills Library
Programming · Learning & explanation

ruby-oop

/ruby-oop

Use when working with Ruby's object-oriented programming features including classes, modules, inheritance, mixins, and method visibility.

Repository
han ↗
Licence
Apache-2.0
Last repository change
08.09.2026

Assessment and security

95/ 100Class: good
Format20 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
1
Scripts
0
HTML comments
0
URLs in SKILL.md
0
Deprecation

No signals detected. Repository changed on 08.09.2026, without references to retired models or APIs.

Licence

Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.

What it does and when to use it

Use when working with Ruby's object-oriented programming features including classes, modules, inheritance, mixins, and method visibility.

Original author description

Use when working with Ruby's object-oriented programming features including classes, modules, inheritance, mixins, and method visibility.

How it works

  1. Class Definition
  2. Inheritance
  3. Modules and Mixins
  4. Advanced OOP Patterns
  5. Struct and OpenStruct
  6. Composition Over Inheritance
  7. Comparable and Enumerable
  8. Class Variables vs Instance Variables
  9. Best Practices
  10. Anti-Patterns
Original SKILL.md headings · 396 lines, 840 words
SKILL.md preview
---
name: ruby-oop
user-invocable: false
description: Use when working with Ruby's object-oriented programming features including classes, modules, inheritance, mixins, and method visibility.
allowed-tools:
  - Bash
  - Read
  - Write
  - Edit
---

# Ruby Object-Oriented Programming

Master Ruby's elegant object-oriented programming features. Ruby is a pure object-oriented language where everything is an object.

## Class Definition

### Basic Class Structure

```ruby
class Person
  # Class variable (shared across all instances)
  @@count = 0

  # Constant
  MAX_AGE = 150

  # Class method
  def self.count
    @@count
  end

  # Constructor
  def initialize(name, age)
    @name = name  # Instance variable
    @age = age
    @@count += 1
  end

  # Instance method
  def introduce
    "Hi, I'm #{@name} and I'm #{@age} years old"
  end

  # Attribute accessors (getter and setter)
  attr_accessor :name
  attr_reader :age      # Read-only
  attr_writer :email    # Write-only
end

person = Person.new("Alice", 30)
puts person.introduce
person.name = "Alicia"
```

### Method Visibility

```ruby
class BankAccount
  def initialize(balance)
    @balance = balance
  end

  # Public methods (default)
  def deposit(amount)
    @balance += amount
    log_transaction(:deposit, amount)
  end

  def balance
    format_currency(@balance)
  end

  # Protected methods - callable by instances of same class/subclass
  protected

  def log_transaction(type, amount)
    puts "[#{type}] #{amount}"
  end

  # Private methods - only callable within this instance
  private

  def format_currency(amount)
    "$#{amount}"
  end
end
```

## Inheritance

### Single Inheritance

```ruby
class Animal
  def initialize(name)
    @name = name
  end

  def speak
    "Some sound"
  end
end

class Dog < Animal
  def speak
    "Woof! My name is #{@name}"
  end

  # Call parent method with super
  def introduce
    super  # Calls parent's speak method
    puts "I'm a dog"
  end
end

dog = Dog.new("Buddy")
puts dog.speak
```

### Method Override and Super

```ruby
class Vehicle
  def initialize(brand)
    @brand = brand
  end

  def start_engine
    puts "Engine starting..."
  end
end

class Car < Vehicle
  def initialize(brand, model)
    super(brand)  # Call parent constructor
    @model = model
  end

  def start_engine
    super  # Call parent method
    puts "#{@brand} #{@model} is ready to drive"
  end
end
```

## Modules and Mixins

### Module as Namespace

```ruby
module MyApp
  module Utils
    def self.format_date(date)
      date.strftime("%Y-%m-%d")
    end
  end
end

MyApp::Utils.format_date(Time.now)
```

### Module as Mixin

```ruby
module Swimmable
  def swim
    "I'm swimming!"
  end
end

module Flyable
  def fly
    "I'm flying!"
  end
end

class Duck
  include Swimmable  # Instance methods
  include Flyable

  def quack
    "Quack!"
  end
end

duck = Duck.new
puts duck.swim
puts duck.fly
```

### Extend vs Include

```ruby
module Greetable
  def greet
    "Hello!"
  end
end

class Person
  include Greetable  # Adds as instance method
end

class Company
  extend Greetable   # Adds as class method
end

Person.new.greet    # Works
Company.greet       # Works
```

## Advanced OOP Patterns

### Singleton Pattern

```ruby
class Database
  @instance = nil

  private_class_method :new

  def self.instance
    @instance ||= new
  end

  def connect
    puts "Connected to database"
  end
end

db1 = Database.instance
db2 = Database.instance
db1.object_id == db2.object_id  # true
```

### Method Missing (Dynamic Methods)

```ruby
class DynamicAttributes
  def method_missing(method_name, *args)
    attribute = method_name.to_s

    if attribute.end_with?("=")
      # Setter
      instance_variable_set("@#{attribute.chop}", args.first)
    else
      # Getter
      instance_variable_get("@#{attribute}")
    end
  end

  def respond_to_missing?(method_name, include_private = false)
    true
  end
end

obj = DynamicAttributes.new
obj.name = "Ruby"
puts obj.name  # "Ruby"
```

### Class Instance Variables

```ruby
class Product
  @inventory = []

  class << self
    attr_accessor :inventory

    def add(product)
      @inventory << product
    end
  end
end

Product.add("Laptop")
```

## Struct and OpenStruct

### Struct (Immutable-ish)

```ruby
Person = Struct.new(:name, :age) do
  def introduce
    "I'm #{name}, #{age} years old"
  end
end

person = Person.new("Bob", 25)
puts person.name
person.age = 26
```

### OpenStruct (Dynamic Attributes)

```ruby
require 'ostruct'

person = OpenStruct.new
person.name = "Charlie"
person.age = 30
person.email = "charlie@example.com"

puts person.name
```

## Composition Over Inheritance

```ruby
class Engine
  def start
    "Engine started"
  end
end

class Wheels
  def rotate
    "Wheels rotating"
  end
end

class Car
  def initialize
    @engine = Engine.new
    @wheels = Wheels.new
  end

  def start
    @engine.start
  end

  def drive
    @wheels.rotate
  end
end
```

## Comparable and Enumerable

### Making Classes Comparable

```ruby
class Person
  include Comparable

  attr_reader :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def <=>(other)
    age <=> other.age
  end
end

people = [Person.new("Alice", 30), Person.new("Bob", 25)]
puts people.sort.map(&:age)  # [25, 30]
```

## Class Variables vs Instance Variables

```ruby
class Counter
  @@count = 0      # Class variable (shared)
  @instances = []  # Class instance variable (not shared with subclasses)

  def initialize
    @@count += 1
  end

  def self.count
    @@count
  end
end
```

## Best Practices

1. **Prefer composition over inheritance** for complex relationships
2. **Use modules for mixins** to share behavior across unrelated classes
3. **Keep classes small and focused** (Single Responsibility Principle)
4. **Use attr_accessor/reader/writer** instead of manual getters/setters
5. **Make use of private/protected** to encapsulate implementation details
6. **Prefer instance variables** over class variables to avoid unexpected sharing
7. **Use Struct for simple data objects** instead of full classes
8. **Override to_s for debugging** to provide meaningful string representations

## Anti-Patterns

❌ **Don't use class variables unnecessarily** - they're shared across inheritance hierarchy
❌ **Don't create god objects** - keep classes focused and small
❌ **Don't expose internal state** - use methods instead of direct instance variable access
❌ **Don't overuse inheritance** - prefer composition or modules
❌ **Don't ignore visibility modifiers** - they exist for encapsulation

## Related Skills

- ruby-metaprogramming - For dynamic class/method generation
- ruby-blocks-procs-lambdas - For functional programming patterns
- ruby-modules - For advanced module usage

Versions

The database has no other skills named ruby-oop.

Database snapshot: 13.11.2026 · package version fe2a62e5c9fd (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 100r-oop
    R object-oriented programming guide for S7, S3, S4, and vctrs. Use when designing R classes or choosing an OOP system.
  • 95python-scala-oop
    Guide for translating Python classes, inheritance, and object-oriented patterns to Scala. Use when converting Python code with classes, dataclasses, abstract classes, inheritance, properties, static methods, class methods, or design patterns.
  • 100ruby-expert
    Expert-level Ruby development with Rails, modern features, testing, and best practices. Use when the user mentions Ruby on Rails, RSpec, gem, Sinatra, or metaprogramming, or when the task involves Ruby 3+ Features, Object-Oriented, Functional Features, or Pattern Matching.
  • 90oop-guide
    Use when designing class hierarchies or applying OOP principles. Triggers on prompts about classes, inheritance, polymorphism, encapsulation, SOLID, design patterns, or interfaces, even when the user doesn't say 'OOP'.
  • 95ruby-metaprogramming
    Use when working with Ruby metaprogramming features including dynamic method definition, method_missing, class_eval, define_method, and reflection.
  • 90ruby
    This skill should be used when conducting spec interviews or implementing specs for Ruby projects, or when the spec mentions "Ruby", "RSpec", "service objects", "Struct", or Ruby class/module patterns. Provides Ruby-specific interview and implementation checklist items.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.