Classes and Objects in Ruby
Ruby is a thoroughly object-oriented language: every value you manipulate -- numbers, strings, arrays, even classes themselves -- is an object, an instance of some class. A class is a blueprint that defines what data (state) and behavior (methods) its instances will have. You define a class with the class keyword, give it instance methods that operate on individual objects, and typically define an initialize method that runs automatically when you create a new instance with ClassName.new(...), setting up that object's starting state.
Cricket analogy: Ruby treating everything as an object is like a cricket board treating every entity -- a player, a bat, even a tournament format -- as a registered object with its own record; a Player class is the blueprint template, and Player.new('Kohli') runs an initialize that sets up that specific player's starting stats.
Defining a class and the initialize method
initialize is a special private method Ruby calls automatically whenever .new is invoked on a class; whatever arguments you pass to .new are forwarded to initialize. Inside it, you typically assign incoming values to instance variables (prefixed with @), which persist for the lifetime of that object and are accessible from any instance method on the same object.
Cricket analogy: initialize is like the automatic pre-match ritual that runs the moment a new player is registered for a series -- whatever kit size and jersey number you provide get set as that player's starting instance data, persisting across every match they play.
class BankAccount
def initialize(owner, balance = 0)
@owner = owner
@balance = balance
end
def deposit(amount)
raise ArgumentError, "amount must be positive" unless amount.positive?
@balance += amount
end
def balance
@balance
end
end
account = BankAccount.new("Wren", 100)
account.deposit(50)
account.balance # => 150Instance methods and object identity
Methods defined inside a class body (without self. prefix) are instance methods -- they're called on individual objects and operate on that object's own instance variables via implicit self. Every object also has a unique identity, inspectable with object_id, and Ruby distinguishes between value equality (==), identity equality (equal?), and same-class comparison (eql?), which matters when two BankAccount instances happen to share the same owner and balance but are still distinct objects in memory.
Cricket analogy: Instance methods are like a specific batter's own technique -- player.play_shot operates on that player's own stats via implicit self, and two players named 'Sharma' with the same average are still distinct people (equal? false) even though their stats compare equal (== true).
a1 = BankAccount.new("Wren", 100)
a2 = BankAccount.new("Wren", 100)
a1.equal?(a2) # => false, different objects
a1.object_id == a2.object_id # => falseUnlike Java or C#, Ruby has no separate 'primitive' types -- integers, booleans, and even nil are full objects with their own classes (Integer, TrueClass, NilClass). You can call methods on them directly, e.g. 5.times { } or nil.to_s, which is why Ruby's object model feels so uniform compared to languages with a primitive/object split.
Forgetting the @ sigil turns what you intended as an instance variable into a plain local variable, which silently disappears once the method returns instead of raising an error. This is a very common beginner bug: def initialize(name); name = name; end does nothing useful, while @name = name correctly stores state on the object.
Class methods versus instance methods
A method defined with def self.method_name (or inside a class << self block) belongs to the class itself rather than to instances, and is called as ClassName.method_name. Class methods are commonly used for factory-style constructors or utility functions that don't need a specific instance's state, such as BankAccount.from_json(data).
Cricket analogy: A class method like def self.from_scorecard is like a records office that generates a new player profile directly from a historical scorecard PDF, without needing any existing player instance -- called as Player.from_scorecard(data), it's a factory that builds instances rather than acting on one.
class BankAccount
def self.zero_balance(owner)
new(owner, 0)
end
end
BankAccount.zero_balance("Priya").balance # => 0- A class is a blueprint; an object (instance) is created from it via
ClassName.new(...), which triggersinitialize. - Instance variables (prefixed
@) hold per-object state and are accessible from any instance method on that object. - Every Ruby value is an object of some class -- there are no primitive types separate from the object system.
- Instance methods operate on individual objects; class methods (
def self.method) belong to the class itself. equal?checks object identity,==checks value equality (often overridden), andobject_idgives a unique identifier.- Forgetting the
@sigil silently creates a throwaway local variable instead of persistent object state.
Practice what you learned
1. What triggers the `initialize` method to run?
2. What is the effect of writing `def initialize(name); name = name; end` instead of `@name = name`?
3. How do you define a method that belongs to the class itself rather than instances?
4. Which statement about Ruby's object model is true?
5. What does `a1.equal?(a2)` check?
Was this page helpful?
You May Also Like
attr_accessor and Instance Variables
Learn how instance variables hold per-object state in Ruby, and how attr_accessor, attr_reader, and attr_writer generate boilerplate getter and setter methods.
Inheritance in Ruby
See how Ruby classes extend one another with single inheritance, how `super` calls parent implementations, and how method resolution order determines which method runs.
Modules and Mixins
Discover how Ruby modules group related methods and constants, and how mixing them into classes with include, extend, and prepend enables flexible code reuse without multiple inheritance.
Method Visibility
Learn how Ruby's public, private, and protected keywords control which parts of an object's interface callers can access, and why visibility shapes good API design.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics