Classes and Objects in Ruby
Ruby is a pure object-oriented language - everything is an object! Understanding classes and objects is essential for mastering Rails, where models, controllers, and everything else are classes.
Creating a Class
ruby
1class User
2 # Class body
3end
4
5# Creating an instance (object)
6user = User.newInstance Variables and Methods
ruby
1class User
2 # Initialize method (constructor)
3 def initialize(name, email)
4 @name = name # Instance variable
5 @email = email # Instance variable
6 end
7
8 # Instance method
9 def greet
10 "Hello, I'm #{@name}!"
11 end
12
13 # Getter method
14 def name
15 @name
16 end
17
18 # Setter method
19 def name=(new_name)
20 @name = new_name
21 end
22end
23
24user = User.new("John", "john@example.com")
25user.greet # => "Hello, I'm John!"
26user.name # => "John"
27user.name = "Jane"
28user.name # => "Jane"Attribute Accessors
Ruby provides shortcuts for getters and setters:
ruby
1class User
2 # Creates getter and setter for name and email
3 attr_accessor :name, :email
4
5 # Creates only getter
6 attr_reader :created_at
7
8 # Creates only setter
9 attr_writer :password
10
11 def initialize(name, email)
12 @name = name
13 @email = email
14 @created_at = Time.now
15 end
16end
17
18user = User.new("John", "john@example.com")
19user.name # => "John" (getter)
20user.name = "Jane" # Setter
21user.created_at # => 2024-01-15 10:30:00 (read-only)
22user.password = "secret" # Write-onlyClass Methods and Variables
ruby
1class User
2 # Class variable (shared across all instances)
3 @@count = 0
4
5 def initialize(name)
6 @name = name
7 @@count += 1
8 end
9
10 # Class method
11 def self.count
12 @@count
13 end
14
15 # Alternative syntax for class methods
16 class << self
17 def description
18 "A user in the system"
19 end
20 end
21end
22
23User.new("John")
24User.new("Jane")
25User.count # => 2
26User.description # => "A user in the system"Inheritance
ruby
1class Animal
2 attr_accessor :name
3
4 def initialize(name)
5 @name = name
6 end
7
8 def speak
9 "Some sound"
10 end
11end
12
13class Dog < Animal
14 def speak
15 "Woof!"
16 end
17
18 def fetch
19 "#{@name} is fetching the ball!"
20 end
21end
22
23class Cat < Animal
24 def speak
25 "Meow!"
26 end
27end
28
29dog = Dog.new("Buddy")
30dog.speak # => "Woof!"
31dog.fetch # => "Buddy is fetching the ball!"
32dog.name # => "Buddy" (inherited from Animal)
33
34cat = Cat.new("Whiskers")
35cat.speak # => "Meow!"Super Keyword
Call the parent class method:
ruby
1class Animal
2 def initialize(name)
3 @name = name
4 end
5
6 def info
7 "Name: #{@name}"
8 end
9end
10
11class Dog < Animal
12 def initialize(name, breed)
13 super(name) # Call parent's initialize
14 @breed = breed
15 end
16
17 def info
18 "#{super}, Breed: #{@breed}" # Call parent's info
19 end
20end
21
22dog = Dog.new("Buddy", "Golden Retriever")
23dog.info # => "Name: Buddy, Breed: Golden Retriever"Modules and Mixins
Modules let you share code between classes:
ruby
1# Module for shared behavior
2module Printable
3 def print_info
4 puts "Printing #{self.class.name} information..."
5 instance_variables.each do |var|
6 puts "#{var}: #{instance_variable_get(var)}"
7 end
8 end
9end
10
11module Timestampable
12 def created_at
13 @created_at ||= Time.now
14 end
15
16 def updated_at
17 @updated_at
18 end
19
20 def touch
21 @updated_at = Time.now
22 end
23end
24
25class User
26 include Printable # Include as instance methods
27 include Timestampable
28
29 attr_accessor :name, :email
30
31 def initialize(name, email)
32 @name = name
33 @email = email
34 end
35end
36
37user = User.new("John", "john@example.com")
38user.print_info
39user.created_at
40user.touchInclude vs Extend
ruby
1module Greetable
2 def greet
3 "Hello!"
4 end
5end
6
7class User
8 include Greetable # Adds as instance methods
9end
10
11class Admin
12 extend Greetable # Adds as class methods
13end
14
15User.new.greet # => "Hello!" (instance method)
16Admin.greet # => "Hello!" (class method)Namespacing with Modules
ruby
1module Admin
2 class User
3 def role
4 "admin"
5 end
6 end
7end
8
9module Public
10 class User
11 def role
12 "public"
13 end
14 end
15end
16
17Admin::User.new.role # => "admin"
18Public::User.new.role # => "public"Object Comparison
ruby
1class User
2 attr_reader :id, :name
3
4 def initialize(id, name)
5 @id = id
6 @name = name
7 end
8
9 # Compare by ID
10 def ==(other)
11 self.class == other.class && id == other.id
12 end
13
14 # For use in hashes
15 def eql?(other)
16 self == other
17 end
18
19 def hash
20 id.hash
21 end
22end
23
24user1 = User.new(1, "John")
25user2 = User.new(1, "John Doe")
26user3 = User.new(2, "Jane")
27
28user1 == user2 # => true (same ID)
29user1 == user3 # => false (different ID)Struct (Quick Classes)
For simple data objects:
ruby
1# Quick way to create a class
2User = Struct.new(:name, :email) do
3 def greeting
4 "Hello, #{name}!"
5 end
6end
7
8user = User.new("John", "john@example.com")
9user.name # => "John"
10user.greeting # => "Hello, John!"
11
12# Keyword arguments version
13User = Struct.new(:name, :email, keyword_init: true)
14user = User.new(name: "John", email: "john@example.com")Ruby Object Hierarchy
ruby
1# Everything inherits from Object
2class User
3end
4
5User.ancestors
6# => [User, Object, Kernel, BasicObject]
7
8# Check inheritance
9User.superclass # => Object
101.class # => Integer
111.class.superclass # => Numeric
12"hello".class # => String
13[].class # => Array
14{}.class # => Hash
15
16# Check if object is an instance
17user = User.new
18user.is_a?(User) # => true
19user.is_a?(Object) # => true
20user.instance_of?(User) # => true (exact class only)Classes and objects form the foundation of Ruby. Rails uses these concepts everywhere - from models to controllers to views!
