Understanding Objects and Object Creation in Ruby

January 29, 2025

Ruby is a pure object-oriented language, where everything is an object. Understanding how objects work and how they are created is fundamental for writing efficient, maintainable code. Let’s explore the key elements involved in object creation in Ruby.


Do you need more hands for your Ruby on Rails project?

Fill out our form! >>


1. What is an Object in Ruby?

An object is an instance of a class that has:

  • State (instance variables)
  • Behavior (methods)
  • Identity (unique memory reference)

Example:

class Car
  def initialize(brand, model)
    @brand = brand
    @model = model
  end

  def info
    "#{@brand} #{@model}"
  end
end

car = Car.new("Toyota", "Corolla")
puts car.info # => "Toyota Corolla"

Here, car is an object (instance) of the Car class.


2. Creating Objects in Ruby

Using Classes (Instantiation)

A class serves as a blueprint for creating objects. The new method is used to instantiate objects:

class Animal
end

dog = Animal.new
puts dog.class # => Animal

Using Structs

Structs provide a lightweight way to define objects:

Person = Struct.new(:name, :age)
p1 = Person.new("Alice", 30)
puts p1.name # => Alice

Using OpenStruct (Dynamic Attributes)

require 'ostruct'
person = OpenStruct.new(name: "Bob", age: 25)
puts person.name # => Bob

3. Key Elements of Object Creation

Instance Variables (@var)

Store object-specific data.

class Book
  def initialize(title)
    @title = title
  end

  def show_title
    @title
  end
end

book = Book.new("1984")
puts book.show_title # => "1984"

Class Variables (@@var)

Shared across all instances.

class Counter
  @@count = 0

  def initialize
    @@count += 1
  end

  def self.count
    @@count
  end
end

Counter.new
Counter.new
puts Counter.count # => 2

Class Methods (self.method_name)

Methods that operate at the class level.

class MathHelper
  def self.square(n)
    n * n
  end
end

puts MathHelper.square(4) # => 16

Accessor Methods (attr_*)

Ruby provides shortcuts for defining getters and setters:

class Product
  attr_accessor :name
end

p = Product.new
p.name = "Laptop"
puts p.name # => "Laptop"
  • attr_reader → Getter only.
  • attr_writer → Setter only.
  • attr_accessor → Both.

4. Advanced Object Creation Techniques

Singleton Methods (Defining Methods for One Object Only)

dog = Object.new
def dog.bark
  "Woof!"
end

puts dog.bark # => "Woof!"

method_missing for Dynamic Methods

Intercepts calls to undefined methods.

class DynamicMethods
  def method_missing(method_name, *args)
    "You called #{method_name} with #{args.inspect}"
  end
end

dm = DynamicMethods.new
puts dm.some_method(1, 2, 3) # => "You called some_method with [1, 2, 3]"

define_method for Dynamic Method Creation

class Person
  [:name, :age].each do |attr|
    define_method(attr) do |value|
      instance_variable_set("@#{attr}", value)
    end
  end
end

p = Person.new
p.name("Alice")
p.age(30)

5. Object Cloning & Duplication

dup vs clone

class Car
  attr_accessor :brand
end

car1 = Car.new
car1.brand = "Toyota"

car2 = car1.dup
car3 = car1.clone

puts car2.brand # => Toyota
puts car3.brand # => Toyota
  • dup → Copies the object but does not copy singleton methods.
  • clone → Copies everything, including singleton methods.

6. Object Lifecycle & Finalization

The ObjectSpace Module

Tracks Ruby objects.

puts ObjectSpace.count_objects[:TOTAL] # Count objects in memory

finalize (Garbage Collection Hook)

class Resource
  def initialize
    ObjectSpace.define_finalizer(self, proc { puts "Cleaning up..." })
  end
end

Resource.new
GC.start # Triggers garbage collection

7. Metaprogramming for Object Creation

class_eval for Dynamic Class Creation

MyClass = Class.new do
  def greet
    "Hello!"
  end
end

obj = MyClass.new
puts obj.greet # => "Hello!"

instance_eval for Defining Methods on a Specific Instance

obj = Object.new
obj.instance_eval do
  def speak
    "I'm an object!"
  end
end

puts obj.speak # => "I'm an object!"

Final Thoughts

Ruby provides powerful tools for object creation, including classes, modules, metaprogramming, and dynamic methods. Mastering these techniques allows you to write flexible, efficient, and elegant object-oriented code.

What are your favorite techniques for working with objects in Ruby? Share your thoughts below! 🚀

Leave a comment