DEV Community

Cover image for Basics of Ruby Classes
Max Normand
Max Normand

Posted on • Updated on

Basics of Ruby Classes

Ruby is one of the easiest languages to grasp the concept of OOP (object orientated programming). In particular the power that of POROโ€™s (plain old Ruby objects).

Let's go through a short example using a little robot ๐Ÿค–

Goal specifications

We want to robot to be able to do the following:

  1. Move around ๐Ÿƒโ€โ™‚๏ธ
  2. Return home ๐Ÿ 
  3. Change colour ๐Ÿ”ด๐ŸŸก๐Ÿ”ต
  4. Receive a toy ๐Ÿงธ

To define a class in Ruby itโ€™s quite simple, letโ€™s start.

# Initializing a class
class Robot
  def initialize(north, south, east, west, colour)
    @north = north
    @south = south
    @east = east
    @west = west
    @colour = colour
  end
end
Enter fullscreen mode Exit fullscreen mode

The initializer method is responsible for handling creating new instances of our class. In this method we define what attributes we want our class to have, this can be anything!

Using our class

Now I suggest if you're following along, running a ruby console (assuming you have installed ruby on your machine). To create and play around with our robot.

To create an instance of a class, and assign it to a local variable
robot = Robot.new
As simple as that!

Now we have access to our robot, but we cannot do anything with it. This is where attribute accessors come into play.

You should read more in depth on this. The principle of attribute accessors is that, they give us write and read permissions on our classes instance objects.

# How to access attributes of a class
class Robot
  attr_accessor :north, :south, :east, :west, :colour

  def initialize(north, south, east, west, colour)
    @north = north
    @south = south
    @east = east
    @west = west
    @colour = colour
  end
end
Enter fullscreen mode Exit fullscreen mode

Now if we call our class in irb, we can move our robot by going.

robot = Robot.new(0,0,0,0)

PLEASE NOTE: At this point, if we do not assign a value to these attributes, you will get an error. We will cover how to change this later.

Class methods and Instance methods

There are two fundamental types on methods you can use on classes in ruby. Class methods, which are called only on the class, and instance methods, called only on an instance of the class.

Here is a good article with some more detail.
https://dev.to/adamlombard/ruby-class-methods-vs-instance-methods-4aje

Now, we can update our class with what we have learnt.

class Robot
  attr_accessor :north, :south, :east, :west, :colour

  def initialize(north = 0, south = 0, east = 0, west = 0, colour = "red")
    @north = north
    @south = south
    @east = east
    @west = west
    @colour = colour
  end

  # Class method, only called on the class
  def self.instructions
    'Hello, I am a Robot, I can move in any direction, and I have a colour!'
  end

  # Instance method only called on an instance of the class
  def print_coordinates
    "Hello I am Robot, I am north #{north}, south #{south}, east #{east}, west #{west}"
  end
end
Enter fullscreen mode Exit fullscreen mode

Notice as well I have added placeholder values in the class initializer method. This means we can safely call our class with no values.

Next let's write some methods to make our robot move around, by updating its attributes.

class Robot
  attr_accessor :north, :south, :east, :west, :colour

  def initialize(north = 0, south = 0, east = 0, west = 0, colour = "red")
    @north = north
    @south = south
    @east = east
    @west = west
    @colour = colour
  end

  # Class method, only called on the class
  def self.instructions
    'Hello, I am a Robot, I can move in any direction, and I have a colour!'
  end

  # Instance method only called on an instance of the class
  def print_coordinates
    "Hello I am Robot, I am north #{north}, south #{south}, east #{east}, west #{west}"
  end

  # Updating an attribute on the class
  def move_north(distance)
    self.north = north + distance
  end

  def move_south(distance)
    self.south = south + distance
  end

  def move_east(distance)
    self.east = east + distance
  end

  def move_west(distance)
    self.west = west + distance
  end
end
Enter fullscreen mode Exit fullscreen mode

Notice how I call self on each method. This is because on these instance methods, we want to assign new data to the instance of the class, therefore itself. I suggest reading this for more explanation.

Using Constants

One very handy tool in ruby is the use of constants. I'd explain constants as key bits of data we want to store in memory, that relate to our class. For instance, they are commonly used in Models for important business logic. This data should not change once defined.

Below I have added some constants for our robots colour. Followed up by a method that uses an array of these constants.

# Using constants
class Robot
  attr_accessor :north, :south, :east, :west, :colour

  # Declaring constants
  RED = 'red'.freeze
  BLUE = 'blue'.freeze
  YELLOW = 'yellow'.freeze
  GREEN = 'green'.freeze

  # Declaring an array of constants
  COLOURS = [
    RED,
    BLUE,
    YELLOW,
    GREEN
  ].freeze

  def initialize(north = 0, south = 0, east = 0, west = 0, colour = RED)
    @north = north
    @south = south
    @east = east
    @west = west
    @colour = colour
  end

  # Class method, only called on the class
  def self.instructions
    'Hello, I am a Robot, I can move in any direction, and I have a colour!'
  end

  # Instance method only called on an instance of the class
  def print_coordinates
    "Hello I am Robot, I am north #{north}, south #{south}, east #{east}, west #{west}"
  end

  # Updating an attribute on the class
  def move_north(distance)
    self.north = north + distance
  end

  def move_south(distance)
    self.south = south + distance
  end

  def move_east(distance)
    self.east = east + distance
  end

  def move_west(distance)
    self.west = west + distance
  end

  # Select a random colour
  def change_colour
    self.colour = Robot::COLOURS.sample
  end

  # reset the co-ordinates
  def bring_home
    self.north = 0
    self.south = 0
    self.east = 0
    self.west = 0
  end
end
Enter fullscreen mode Exit fullscreen mode

Look at how our class has grown! Now think of the power we have learnt (evil laugh).

Let's have fun with our instance methods:

robot = Robot.new
robot.move_north(3)
robot.change_colour
robot.bring_home
Enter fullscreen mode Exit fullscreen mode

We have now achieved so much from the spec!

But wait, there's more we can do, and we haven't fulfilled the spec. We need to give our robot a toy, the little fella earnt it, don't you think?

Not only can we pass numbers and strings into our classes, we can also pass... dun dun dun, other classes!

Let's create a toy class. A simple class with a name attribute.

class Toy
  attr_accessor :name

  def initialize(name = 'skateboard')
    @name = name
  end
end
Enter fullscreen mode Exit fullscreen mode

Now, if we pass in another attribute parameter to our robot, as well as define another attribute accessor. We can have full access of the toy within an instance of our robot class.

# Passing in a class instance object to another class

class Robot
  attr_accessor :north, :south, :east, :west, :colour, :toy

  # Declaring constants
  RED = 'red'.freeze
  BLUE = 'blue'.freeze
  YELLOW = 'yellow'.freeze
  GREEN = 'green'.freeze

  # Declaring an array of constants
  COLOURS = [
    RED,
    BLUE,
    YELLOW,
    GREEN
  ].freeze

  def initialize(north = 0, south = 0, east = 0, west = 0, colour = RED, toy)
    @north = north
    @south = south
    @east = east
    @west = west
    @colour = colour
    @toy = toy
  end

  # Class method, only called on the class
  def self.instructions
    'Hello, I am a Robot, I can move in any direction, and I have a colour!'
  end

  # Instance method only called on an instance of the class
  def print_coordinates
    "Hello I am Robot, I am north #{north}, south #{south}, east #{east}, west #{west}"
  end

  # Updating an attribute on the class
  def move_north(distance)
    self.north = north + distance
  end

  def move_south(distance)
    self.south = south + distance
  end

  def move_east(distance)
    self.east = east + distance
  end

  def move_west(distance)
    self.west = west + distance
  end

  # Select a random colour
  def change_colour
    self.colour = Robot::COLOURS.sample
  end

  # reset the co-ordinates
  def bring_home
    self.north = 0
    self.south = 0
    self.east = 0
    self.west = 0
  end
end
Enter fullscreen mode Exit fullscreen mode

Now if you were to call toy = Toy.new and robot = Robot.new(toy), you can successfully met the spec, congratulations!

Conclusion

As you can see creating our own classes in ruby is not only fun, but extremely powerful. If you harness the power of classes in your rails applications, you can create very modular, DRY, and sexy looking code. ๐Ÿ˜˜

I encourage you on your ruby journey, to jump on in a console and have fun! I find it's the best way to learn. Thanks for reading, you're a ๐Ÿ’Ž

Top comments (4)

Collapse
 
lucianghinda profile image
Lucian Ghinda

Hi Max,

Congrats for writing an article about Ruby Classes. We need for sure more fresh content like this one in Ruby world so that people that want to learn Ruby can be inspired.

Thank you for contributing to Ruby community and hope I can read more articles from you.


Hope you don't mind a suggestion: you can have better syntax highlighting if you specify the language when writing code samples.

For example for Ruby if you type ruby after the code markdown it will highlight the Ruby syntax:

Writing this:

Image description

will generate this preview:

Image description

Notice I wrote ruby immediately after the three backticks.

More details about how to do syntax highlighting in the markdown used by Dev.to can be found here


I was not sure how to contact you privately to write this suggestion so please feel free to delete this comment as it is off-topic.

Collapse
 
maxnormand97 profile image
Max Normand

Thanks so much for reaching out Lucian, I didnโ€™t think anyone would even read it! Means a lot โค๏ธ

Thanks as well for pointing out the syntax highlighting! Iโ€™ve been looking around for how to do that ๐Ÿ’Ž

Collapse
 
abdusamadeveloper profile image
abdusamadeveloper

Awesome

Came across this while diving in the ruby world.
Thanks buddy ๐Ÿ˜˜

Collapse
 
maxnormand97 profile image
Max Normand

Thanks so much ๐Ÿ™! Hope your enjoying the world on Ruby ๐Ÿ’Ž