Intro to Ruby Classes

Published in January 2020

What is a Class?

A class is the basic building block in Object Oriented Programming (OOP) (such as Ruby) and is the "blueprint" from which individual objects are created. So for example, Michael Bluth is an instance of the class User and Bulgaria is an instance of the class Country.

Every User has different characteristics which can help you to distinguish between them - name, email, billing address, age and so on.

Every User can also have different methods (functions) - calculate the date of birth, sign up to the newsletter, etc.

Defining a Ruby Class

You can define the class User using the following syntax

class User
  # class logic goes here
end

Notice that classes are defined using the class keyword. Also, class names follow the camel case rule - each word should be uppercase and no spaces are allowed.

Variables in Ruby Class

There are five different types of variables which can be used in a Class:

  • local variables - variables only available in the method that they are defined in. An example of a local variable is local_variable = 5
  • instance variables - variables that are available across methods for an instance of a class. An example of an instance variable is @instance_variable = 5
  • class variables - variables that are available across different objects. You can think of it as a characteristic of the class. To define a class variable, use @@, for example @@class_variable = 5
  • global variables - variables available across different classes. Use the $ symbol, for example $global_variable = 5
  • constants - variables that never change. Even though you only need to uppercase the first letter of a constant, the "Ruby way" of defining a constant is to uppercase the entire variable - CONSTANT_VARIABLE = 5

Creating a Ruby Object from a Class

Objects are instances of a Class. You can use the #new method to create objects

user1 = User.new
# => #<User:0x00007f9b0c8f7718>
user2 = User.new
# => #<User:0x00007f9b0c8f76f0>

The Initialize method

Another thing to remember about classes is that, unlike methods, you do not pass arguments to classes. Instead, you pass arguments to the .new which you can then use to create instance variables for that object.

This is done using the special #initialize method inside the class. If you are familiar with other OOP languages, you might have come across this method as a "constructor".

class User
  def initialize(first_name, last_name, age)
    @first_name = first_name
    @last_name = last_name
    @age = age
  end
end

user = User.new("Tobias", "Funke", 33)
# => #<User:0x00007fb24a835708 @first_name="Tobias", @last_name="Funke", @age=33>

A note should be made that if you pass parameters to the .new method but don't define #initialize within your class, you will get an error.

user = User.new("Tobias", "Funke", 33)
# => wrong number of arguments (given 3, expected 0) (ArgumentError)

If your class doesn't require arguments, you don't have to define #initialize.

Defining instance methods in a class

You can define custom methods within a class. Within the method, you can use the instance variables that you defined in the initialize method.

class User
  # ...
  def greeting
    "Hello, #{@first_name}."
  end
end

p user.greeting
# => "Hello, Tobias."

Remember that every object created by User will have access to the #greeting method.

Getter/Setter

The instance variables that you defined when you created the object can't be used outside of your class unless you create getter and setter methods or use attr_accessor.

p user.first_name
# => undefined method `first_name' for #<User:0x00007fccfe8f90d0> (NoMethodError)

To be able to read the variables and assign it a new value from outside the class, you can define two methods, a getter and a setter, within your class.

class User
  # ...
  def first_name
    @first_name
  end

  def first_name=(name)
    @first_name = name
  end
end

user = User.new("Tobias", "Funke", 33)
p user.first_name
# => "Tobias"
user.first_name = "Lindsay"
p user.first_name
# => "Lindsay"

That's great, but it can be a bit time consuming to have to write all of these methods for every instance variable. Fortunately, Ruby has thought of this problem and created the attr_accessor method which makes our classes a lot shorter and nicer looking.

class User
  attr_accessor :first_name
  # ...
end

This method creates both first_name and first_name= for us. Nice!

Defining class methods

Class methods provide the functionality to the class itself. We use the self keyword to define class methods.

class User
  def self.class_method
    "I am a class method."
  end
  # ...
end

p User.class_method
# => "I am a class method."
p user.class_method
# => undefined method `class_method' for #<User:0x00007fa3350deca8> (NoMethodError)

You should remember that you cannot call instance methods on the class just like you can't call class methods on the instance.

Everything in Ruby is an object

Yes, really! Because everything is an object, everything was created from a class. You can see from which class the object is coming from using the .class method.

p [].class
# Array

p "".class
# String

p user.class
# User

If you know from which class your object is coming from, you then know the list of methods that you can apply on this object. You can check the Ruby documentation for a full list of methods for each class!

Level up your web development skills

Get articles, guides and interviews right in your inbox. Join a community of fellow developers.

No spam. Unsubscribe at any time.

Full Stack Heroes logo

© 2020 Full Stack Heroes