Every Object is an Instance of a Class
In this chapter, you will learn that every class is an instance of a Ruby built-in class called Class.
User Defined Class
Let's take a look at user defined classes.
class Car
def drive
puts 'driving...'
end
end
We can send the drive() message to the car instance car.
car.drive
This prints:
driving...
We created an instance of our car class and called the drive() method.
Car Class is an Object
The class Car we defined is an object. If that is the case, then the Car class must be an instance of some class. What is that class?
class Car
def drive
puts 'driving...'
end
end
p Car.class
This prints:
Class
The Car class is an instance of a class called Class.
The class Keyword
Why is Car class an instance of Ruby's built-in Class? When you use the Ruby language keyword class, Ruby uses Class to create Car object. Ruby does something like this:
Car = Class.new
If you print the class of Car:
p Car.class
It prints:
Class
Creating Car Class using Class
We can rewrite the example like this:
Car = Class.new do
def drive
p 'driving'
end
end
car = Car.new
car.drive
This also prints:
driving
Rhonda Asks
Why would you want to create a Car class using Class.new ?
The reason is that the scope of variables defined before the class definition is visible inside the do-end block.
x = 1
Car = Class.new do
p x
end
This prints 1, but what happens if we define a Car class using the class keyword?
x = 1
class Car
p x
end
This results in:
NameError: undefined local variable or method ‘x’ for Car:Class
The x is not visible inside the class definition. The reason is that the class keyword creates a new scope. Let's verify this by writing a program. We can print the local variables at the top level and inside the Car class.
x = 1
p 'Local variables at top level'
p local_variables
class Car
p 'Local variables inside the class'
p local_variables
end
This prints:
Local variables at top level
[:x]
Local variables inside the class
[]
This shows that at the top level, we have x as the local variable, whereas, inside the Car class, there is none.
Scope of Local Variable Inside a Block
Let's write a simple program to check the local variables at the top level and inside the do-end block of a Class.new call.
x = 1
p 'Local variables at top level:'
p local_variables
Car = Class.new do
p 'Local variables inside the do-end block'
p local_variables
end
This prints:
Local variables at top level:
[:x]
Local variables inside the do-end block
[:x]
This shows that we have the same local variable x at the top level as well as the do-end block.
Methods Defined in Class
The Class is Ruby's built-in class that provides the new() method that we can use to instantiate the car object.
p Class.public_instance_methods(false).sort
This prints:
[:allocate, :new, :superclass]
As a developer you will not call allocate() method. You will use the new() and superclass() methods.
The new Instance Method
Since Car is an object you can call the instance method new like this:
car = Car.new
Because new is an instance method provided by Ruby's built-in class called Class. The above example is like:
car_class = Class.new do
def drive
p 'driving'
end
end
car_object = car_class.new
car_object.drive
Class names in Ruby must begin with Capital letter. That's the reason we don't name a class with lowercase like car_class, we use Car. In this example, the name car_class is used to make it clear that the class Car is an object that can respond to new message.
Summary
In this chapter we saw that the car object is an instance of a user defined Car class. The class can either be user defined or Ruby built-in classes. In the next section, we will see that Ruby built-in classes are also objects.