Learn Ruby - Object Oriented Programming

Question Click to View Answer

Object oriented programming (OOP) is at the core of Ruby, so even beginners need to know the basic OOP principles. OOP discussions tend to get abstract and I have made an effort to make this introduction concrete with examples.

What is the value of the variable x?

x = String.new("i wish i was surfing")
"i wish i was surfing"

String is a class and classes are responsible for making "objects". "i wish i was surfing" is referred to as an object. "i wish i was surfing" is also referred to as an instance of the String class, which means that the String class made the "i wish i was surfing" object. We have been making String objects throughout these quizzes. The following two expressions are the same thing:

x = String.new("i wish i was surfing")
x = "i wish i was surfing"

Make the following object: "i thought he said this wasn't going to be abstract..."

String.new("i thought he said this wasn't going to be abstract...")

What does this return?

"hi".methods()

The methods() method returns an array of the methods that the object can use. The String class is built-in to Ruby and provides a lot of methods that are commonly used, so we don't need to define them ourselves.

What does this return?

"hello".upcase()
"HELLO"

The upcase() method capitalizes all the letters of a string object. In this example, the upcase() method is being called on the object "hello".

What does this return?

"sUp DuDe".swapcase()
"SuP dUdE"

swapcase() is a method that is available to string objects. In this example, the swapcase() method is called on the "sUp DuDe" object.

What does this return?

"This is a sentence, kinda".split()
["This", "is", "a", "sentence,", "kinda"]

What is the syntax for calling methods on string objects? Look at the previous examples and observe the pattern.

string object, followed by dot, followed by the method name

For this example "hello".upcase(), "hello" is the string object and upcase() is the method name

In the "sUp DuDe".swapcase() example, "sUp DuDe" is the string object and swapcase() is the method name

To recap, the String class makes string objects, and the string objects have access to methods like upcase() and downcase(). Create a string object with the text "road trip".

"road trip"
# OR
String.new("road trip")

For the rest of this tutorial, let's stick with the explicit syntax (String.new("road trip")) since it is better for learning.

The explicit syntax makes it clear we are using the String class to make an instance of the String class (also referred to an object). "road trip" is an example of a string object (an object made by the String class).

What does this code return?

Array.new()
[]

Array.new() creates a new array object (the empty array). The empty array is an instance of the Array class, meaning it was created by the Array class. An instance of the Array class is also referred to as an array object or an object.

What does this code print?

my_array = Array.new()
my_array.push("nice")
my_array.push("hair")
puts my_array.inspect
["nice", "hair"]

my_array is an array object and push() is a method that adds elements to an array object. Notice that the same syntax used to call methods for the String class is used here: object, followed by dot, followed by the method name.

Here is how to interpret this example, line-by-line: my_array = Array.new() # An new array object has been created as is assigned to the variable my_array

my_array.push("nice") # The push() method is called on the my_array object to add the String "nice" to the array

my_array.push("hair") 

puts my_array.inspect() # The inspect() method is called on the array object and it is printed

What is a class?

A class can be thought of as a factory that makes objects.

String and Array are examples of classes.

What is an object.

An object is an instance of a class. Objects have methods that can be called to make the object do stuff. For example, the "hello" string object has the upcase() method. When the upcase() method is called on "hello" (i.e. "hello".upcase()) the "hello" object knows to create another object "HELLO".

"blah" is an example of an object that is created from the String class.

["one", "two"] is an example of an object that is created from the Array class.

How is a String object created?

String.new("bob") will create the "bob" object. The syntax for creating an object from a class is: class name, followed by dot, followed by the new method and the string name as an argument.

Create a new Hash object.

Hash.new()

Creating a Hash object follows the same pattern: class name, followed by dot, followed by the new() method

Create a new Array object and add two string objects to it: "fun" and "games".

a = Array.new()
a.push(String.new("fun"))
a.push(String.new("games"))

What does the following code evaluate to?

my_string = String.new("special")
my_string.push("cool")

This code raises an error. The push() method is defined for Array objects, but is not defined for String objects. There are some overlapping methods between classes (i.e. array objects and string objects both respond to the length() method), but other methods do not overlap.

What does the following code evaluate to?

a_string = String.new("ear")
a_string.class()
String

The class() method returns the name of the class that created the object. The String class created the a_string object, so the class() method correctly returns String.

What does the following code evaluate to?

an_array = Array.new()
an_array.class()
Array

an_array is an Array object that was created by the Array class. The class() method returns Array because the an_array object was created by the Array class.

So far, we have explored classes defined by the Ruby programming language, but we can also create our own classes.

This code creates an Animal class.

class Animal
end

Create an instance of the Animal class and assign it to the variable fido.

fido = Animal.new()

To create an instance of the Animal class, we use the class name, followed by dot, followed by the new() method. fido is also referred to as an object or an animal object.

This code is used to create a Dog class with a speak() method.

class Dog
  def speak()
    return("ruff ruff")
  end
end

Create an instance of the Dog class and assign it to the variable spot. Then call the speak() method on the spot dog object.

spot = Dog.new()
puts spot.speak()

After the spot object is created, the speak() method can be called.

Define a Penguin class with a looks() method that returns "We are cute!".

class Penguins
  def looks()
    "We are cute!"
  end
end

The following code creates a Fish class with a general_overview() class method.

class Fish
  def self.general_overview()
    return("Fish are animals that live in the sea")
  end
end

Call the general_overview() method on the Fish class.

puts Fish.general_overview()

Notice that class methods are called directly on the class itself. An instance of the Fish class (a fish object) does not need to be created to call the general_overview() method. The following code does not work because general_overview() cannot be called on an instance of the Fish class, it can only be called on the Fish class itself:

nemo = Fish.new
puts nemo.general_overview() # doesn't work

Define a Calculator class with an add() class method. Demonstrate how the add() method can be called to add two numbers.

class Calculator
  def self.add(x, y)
    return(x + y)
  end
end

puts Calculator.add(3, 4)

Here is how to define a Person class that is instantiated with a name.

class Person
  def initialize(name)
    @name = name
  end
end

Identify the key components of this code.

initialize() # a special method that is run when Person.new() is executed.  

@name # an instance variable that is used to maintain state in a Ruby class.  The @name instance variable can be used by instance methods throughout the Person class and this is a powerful object oriented programming technique.

Here is how to create a Person object with the name "Fred".

class Person
  def initialize(name)
    @name = name
  end
end

my_person_object = Person.new("Fred")

Explain how the my_person_object was instantiated.

The new() method was called on the Person class with the argument "Fred". The new() method automatically calls the initialize() method and passes the "Fred" argument to the initialize() method. The body of the initialize() method sets @name = "Fred". @name is a variable, but is a special type of variable called an instance variable that is used to retain state of the object. The @name instance variable can be used by the instance methods in the Person class, which is incredibly useful.

Here is how to create a Lion class with a name instance variable and a method that returns the name.

class Lion
  def initialize(name)
    @name = name
  end

  def return_lions_name
    return(@name)
  end
end

simba = Lion.new("Simba")
puts simba.return_lions_name() # prints "Simba"

Explain how the return_lions_name() method works.

The return_lions_name() method simply returns the value that is stored in the @name instance variable. The @name instance variable is accessible by all instance methods in the Lion class and return_lions_name() is an instance method of the Lion class. An instance method that returns the value of the @name instance method is typically called name(), so here is how the class looks when following Ruby conventions:

class Lion
  def initialize(name)
    @name = name
  end

  def name
    return(@name)
  end
end

Create a Celsius class that is initialized with temperature.

class Celsius
  def initialize(temperature)
    @temperature = temperature
  end
end

Add a method to_fahrenheit() to the Celsius class that converts the Celsius temperature to Fahrenheit. The formula to convert Celsius to Fahrenheit is the temperature in Celsius times 1.8 plus 32.

class Celsius
  def initialize(temperature)
    @temperature = temperature
  end

  def to_fahrenheit()
    return(@temperature * 1.8 + 32)
  end
end

celsius = Celsius.new(10)
puts celsius.to_fahrenheit()