Classes

Blueprints for creating objects. They define attributes and methods that objects instantiated from the class will have. Instance variables are prefixed with @. Class variables are prefixed with @@

class Person
 @@species = "homo sapien" # class var
  attr_accessor :name, :age # provides getter and setter methods
 
  def initialize(name, age)
    @name = name # instance var
    @age = age
  end
 
 
  def self.species # exposes class variable
    @@species
  end
end
 
person = Person.new("Alice", 25)
puts "I am a #{Person.species}"

Methods

Different types of methods include: instance methods, class methods, and module methods.

class Person
  attr_accessor :name
 
  def initialize(name)
    @name = name
  end
 
  # instance methods operate on the instance
  def greet
    "Hi, I'm #{@name}."
  end
 
  # class methods operate on the class itself
  def self.info # self refers to the class
    "This is a Person class."
  end
end
 
person = Person.new("Alice")
puts person.greet # Hi, I'm Alice.
puts Person.info # This is a Person class.

Modules (mixins)

Modules can be mixed into classes using include (as instance method) or extend (as class method)

module Flyable
  def fly # module method
    "I can fly!"
  end
end
 
class Bird
  include Flyable # module method will operate on instance
end
 
class Plane
  extend Flyable # module method will operate on class
end
 
bird = Bird.new
puts bird.fly       # I can fly!
puts Plane.fly      # I can fly!

Singleton Methods

Defines methods for a single object instance

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

Inheritance

A class can inherit from another using <. super initializes the parent class.

class Animal # parent class
  attr_reader :species
 
  def initialize(species)
    @species = species
  end
end
 
class Dog < Animal # child class
  attr_reader :name
 
  def initialize(name)
    super("Dog") # passes init args to parent class
    @name = name
  end
end
 
dog = Dog.new("Buddy")
puts "#{dog.species} #{dog.name}" # Dog Buddy

Polymorphism/Overriding

A subclass can redefine methods from its parent class

class Animal
  def speak
    "Some generic sound"
  end
end
 
class Cat < Animal
  def speak
    "Meow!"
  end
end
 
animals = [Animal.new, Cat.new]
animals.each do |animal|
  puts animal.speak # Some generic sound, Meow!
end

Encapsulation

Methods may be:

  • Public: default, accessible anywhere
  • Private: can only be called within the class
  • Protected: can be accessed by instances of the same class or its subclasses.
class Person
  def initialize(name, secret)
    @name = name
    @secret = secret
  end
 
  def introduce
    "Hi, I'm #{@name}."
  end
 
  private # methods below this are private
 
  def reveal_secret
    @secret
  end
 
end
 
person = Person.new("Alice", "I love Ruby.")
puts person.introduce # Hi, I'm Alice.
puts person.reveal_secret  # errors

Reusing Code

Blocks

Chunks of code that can be passed to methods. Defined using {} or do..end

def greet_with_block(name)
  yield(name) if block_given? # yields to the block, if block is given
end
 
greet_with_block("Alice") { |name| puts "Hello, #{name}!" } # Hello, Alice!

Procs and Lambdas

Procs are objects that hold blocks of code

add = Proc.new { |a, b| a + b }
puts add.call(2, 3) # 5
puts add.call(2) # 2

Lambdas are Procs with strict argument checking

add = -> (a, b) { a + b }
puts add.call(2, 3) # 5
puts add.call(2) # errors, wrong number of arguments

Manipulating Built-ins

Built-in classes like String or Array can be modified

class Array
  def average
    sum.to_f / size
  end
end
 
numbers = [1, 2, 3, 4, 5]
puts numbers.average # 3.0

Special Methods

Built in methods can be overridden to customize behavior

class Person
  def initialize(name, age)
    @name = name
    @age = age
  end
 
  def to_s # string representation
    "Name: #{@name}, Age: #{@age}"
  end
 
  def inspect # used for debugging
    "#<Person: #{@name}, #{@age}>"
  end
end
 
person = Person.new("Alice", 30)
puts person.to_s     # Name: Alice, Age: 30
puts person.inspect  # #<Person: Alice, 30>