II Classes

Classes are templates for creating objects. Just as CSS classes allow properties to be applied to multiple HTML elements, Ruby classes allow behavior to be shared between multiple objects.

Classes contain the code that tells objects how to respond to messages. The String class knows how to reverse a string. The Fixnum and BigNum classes knows how to add whole numbers together.

Every object is an instance of a class. We can send the class message to an object to ask about its class.

1.class       # => FixNum
3.14.class    # => Float
'hello'.class # => String
:hello.class  # => Symbol
true.class    # => TrueClass
false.class   # => FalseClass
nil.class     # => NilClass
999999999999999999999.class # => BigNum

6. A Class for HTML Divs

Let’s create a Ruby class for one of the most commonly-used HTML elements, the <div>.

Here’s a sample div:

<div>Hello World!</div>

The two important things to note here are that divs have an opening and closing tag and that they can have content.

Let’s start building the class. In Ruby, the standard way to write class names is CamelCased, with the first letter of each word capitalized and no spaces.

class Div
end

Although Ruby provides shortcuts for creating instances of the String, FixNum, Symbol, and other commonly-used classes, the standard way to create an instance of a class is to tell the class to create new object. We do this by sending the new message to the class.

Div.new

To make our Div objects useful, we need the ability to put content into them and convert them to HTML. To do this, we need to add some methods. Methods are blocks of code that tell objects how to respond to specific messages.

In Ruby, methods are defined using def followed by the method name in snake-case format, just like variables. Methods are terminated using the end keyword. The last line of a method determines what is returned from the method.

def method_that_returns_the_number_one
  1
end

7. The initialize Method

We want the ability to give our divs content when we create them.

Div.new('Hello World!')

When a class receives the new message, it creates a new instance of that class and sends the initialize message to the new object. To control what happens when the object receives this message, we need to define the initialize method and have it accept a parameter for the content. Parameters are variables that hold the data that is passed to a method.

class Div
  def initialize(content)
  end
end

The Div class now expects content to be passed to it when creating a new instance.

Div.new('Hello World!')

What happens if we try to create a Div without content?

Div.new
# => ArgumentError: wrong number of arguments (0 for 1)

An argument is a piece of data passed to a method. Arguments and parameters are thrown around interchangeably because they are so closely related, but they are not exactly the same. Here’s an example to show the difference between the two.

Parameters vs Arguments

When you define a method, the objects that it accepts are the parameters.

def a_method(first_parameter, second_parameter)
end

When you call that method, the objects that you pass into it are the arguments.

a_method('first argument', :second_argument)

The arguments sent to the method are placed into the parameter variables.

The initialize method is expecting an argument for the content parameter. Since we didn’t provide one, Ruby raised an exception. Since empty divs are common in HTML documents, we need to fix this problem. We can tell initialize that the default the value of content should be an empty string. Then, when Div.new is called without any arguments, the content parameter will contain an empty string.

def initialize(content = '')
end

We can now create empty and non-empty divs without raising exceptions.

Div.new
Div.new('Hello World!')

8. Instance Variables

Unfortunately, we aren’t storing the content anywhere. So, after initialize is executed, the content is gone forever. To store the content, we need to put it into an instance variable. Instance variables hold data that belongs to an object. They start with a @.

Let’s modify the initialize method so it stores the content.

def initialize(content = '')
  @content = content
end

Now, when we create a new Div and pass in some content, the content is stored for later use.

9. The to_s Method

The to_s method (short for “to string”) determines how an object responds when converted into a string.

Let’s add a to_s method to our Div class and have it return a string containing the HTML markup for a div.

def to_s
  '<div></div>'
end

print and puts are two methods that Ruby provides for outputting strings. The difference between them is that puts includes a new line at the end of the string while print does not.

Now, we can run puts Div.new and it will print out <div></div>.

10. String Interpolation

The last step in making our Div class useful is to include the value of the @content variable between the opening and closing tags. We can do this via string interpolation. Interpolation is a fancy term for executing code in a string. In Ruby, this is done by wrapping the code in #{} inside the string.

NOTE: This only works for strings wrapped in double quotes (“”). Strings wrapped in single quotes (‘’) will not be interpolated.

Let’s update our to_s method to include the content.

def to_s
 "<div>#{@content}</div>"
end

Now, when we print a Div, the content we passed into Div.new is included in the output.

puts Div.new('Hello World!') # => "<div>Hello World!</div>"
puts Div.new # => “<div></div>”

11. The Code

Here’s the complete Div class along with an example of how to use it.

class Div
  def initialize(content = '')
    @content = content
  end

  def to_s
    "<div>#{@content}</div>"
  end
end

puts Div.new('Hello World!') # => "<div>Hello World!</div>"