Sage-Code Laboratory
index<--

Ruby Classes

Ruby is a pure Object Oriented language. That means everything is an object. Even the literals are objects. You can use dot notation with literals to call methods or properties of literals: For example 42.to_s == "42". If it looks weird to you it's OK, because it is weard!

Object Oriented

In HTML document, you can define a "class" for each element. This will help you create style in CSS that apply to multiple elements having the same "class". This approach is very similar to object oriented programming.

The concept of a "class" represents a "category" of objects. We can describe an object with features and behavior, but the description is not the object itself. We can have multiple objects having the same description.

In Object Oriented programming, the description of object is called "class". The object that comply with this description is called "class instance". We can have many instances for a class. Each instance can be a bit different.

For example a "vase" has volume 1 liter, handle and color green while other "vase" can have 2 liters, no handle and color purple. Both objects are "vases", but they have different attributes. In computer science a class can have "properties" while and object can have "attributes".

OOP principles

Object Oriented programming has four main principles, called the pillars of OOP programming:

  1. Abstraction: you can define abstract classes and interfaces,
  2. Encapsulation: you can define public and private properties and methods,
  3. Inheritance: one class can inherit properties and methods from a parent class,
  4. Polymorphism: one method in a parent class can be overwritten in a child class.

Class Syntax

In Ruby a class can be derived from another class. All classes have a single root class named: BasicObject. When you define a class you can specify the base class using symbol "<", this is very close to the mathematics symbol "<:" that represents a "sub-type".

Example:

# define a simple class with constructor

class Dog < Object
    def initialize(name)
        @name = name # attribute declaration
    end
    def bark # method
        puts "ham ham"
    end
    def breed=(breed)  # attribute writer
        @breed = breed
    end
    def breed  # attribute reader
        @breed 
    end
end

# first instance of Dog
dog1 = Dog.new("rex")
dog1.breed = "buldog"
dog1.bark

# second instance of Dog
dog2 = Dog.new("bear")
dog2.breed = "labrador"
dog2.bark

# use reader
puts dog1.breed
puts dog2.breed

Notes: 

Observation: In other languages, instance variables (attributes) can be directly visible using dot notation. But in Ruby, instance variables can only be read or write using access functions: readers and writers. In other languages these two are known as "get" and "set" methods. If you are an idiot like me you will have hard time understanding this.

Warning: If you try to read an attribute by name using dot notation you will get an error. Ruby will try to find a method, with name equal to attribute name. If the method do not exist (you do not have a reader) then you get an error message. 

Homework: Open this example live and run it: create class

Using Ruby Blocks

A cool pattern you can use with ruby blocks is to initialize an object with default values. This method enable you to create dynamic constructors that initialize the object after creation.

The way it works is, you have an initializer that calls yield(self). In the context of the initialize method, self is the object being initialized.
# define a class that require initializer block
class Car
  attr_accessor :color, :doors

  def initialize
    yield(self)
  end
end

# call class constructor with a muly-line block argument
car = Car.new do |c|
  c.color = "Red"
  c.doors = 4
end

puts "My car's color is #{car.color} and it's got #{car.doors} doors."

Output:

My car's color is Red and it's got 4 doors.

Read next: Frameworks