loading...
Cover image for Exploring Self

Exploring Self

torianne02 profile image Victoria Crawford ・5 min read

As many of you know, I have recently become a software engineering coach for the bootcamp I attended. While going through our first module it appeared that a lot of our students had a tough time grasping the concept of self. At first, I fumbled around with explaining it in the simplest words. This really woke me up because I pride myself on writing blog posts in simple terms that are easy for beginners to understand.

I know with great thought, I can explain things in a simple way, but on the spot, I struggle. I want to get better at this and to accomplish this, it means I need to gain a deeper understanding of the topic. So, here I am writing this lovely blog post on the concept of self in Ruby.

Let's get started.

What is self?

In Ruby, self is a tool that allows developers to refer to a particular object or class. Grasping the concept of self could be difficult because the object or class that self refers to changes. The way self changes is reliant upon the context in which it is being called in.

There are many different contexts in which self can appear and I am going to do my best to cover as many as I can think of. Forgive me if I leave one or two out. If you know of a few others and want to include them in the comments below to add to the discussion, please do so!

Top Level Self Context

Outside of any Ruby class, method, module, etc. self refers to the top level, which is an object called main. This main object exists in an empty .rb file. Ruby is an object oriented language, so even within an empty .rb there is an object! Pretty cool, huh?!

Top Level Self Code Snippet

Module Self Context

Within a module, the context of self refers to the module. If it helps, you could think of self in this context as just referring to the name of the module. So, if we have a Pet module and we called self it would output Pet.

Module Level Self Code Snippet

Class Self Context

The context of self in a class is very similar to that of a module. self refers to the class that it is in and can also be a substitute of the class name itself. So, if we have a Dog class and we called self it would output Dog.

Class Level Self Code Snippet

Seems pretty simple, right? Well, at this point, it is! It's in the next two contexts that things seem to get a little confusing.

Class Method Self Context

This is where things start to get a little tricky and harder to grasp. Hopefully you have an idea of what a class method looks like. If not, it is a method that has self. prepended to the method name. In the context of class methods, self points to the class itself. It does not point to the instance of a class, but to the class as a whole.

For a simple example, let's say we have a class variable called @@name and we wanted to be able to get it outside of the class. In order to accomplish this, we need a class method.

Simple Class Method Example

In self.name, I used puts self to retrieve what self is pointing to within this class method. If you noticed, it's pointing to the Dog class not an instance of it.

The way we call class methods is by using the class name, in our case it is Dog, followed by the name of the method. So, if we called Dog.name outside of the class the output would be Buddy.

Diving Deeper

Alright, so, let's dive in and think about this Dog class in a broader way. Let's say a dog is having puppies. Each new puppy that is born is a new instance of the Dog class. So if a dog has 4 puppies, there would be 4 new instances of the Dog class.

Well, as great dog owners, we want to keep track of all the dogs we have by creating an @@all variable which we'll set to an empty array. Each time that one of the puppies is born, we pass the new instance of the Dog class that is created into this @@all variable. This way, we have all of the dogs in one place! (I'll dive into more context on how and where this should happen later.)

If we want to return this array of all of our dogs, we must create another one of those handy class methods to get the array.

@@all Class Method Code Snippet

If we called Dog.all it would return the array of all instances of the Dog Class that have been created, which means self is pointing to the class itself and not an instance of the class.

Class Instance Method Self Context

You know how before I mentioned we'd discuss where and how we'd add each new instance of the Dog class to the @@all array? Well, here we go!

initialize

In this case, we want to create an initialize method which is called on any time a new instance of a class is created. Our initialize method takes a :name and :breed and also adds this new instance to the @@all variable by calling self.

Let's pause for a second. Thinking about everything I just said, what do you think self will refer to when called in the initialize method?

If you guessed that self points back to the new instance of the class being created, you are correct!

Intialize Method Code Snippet

To make sense of this, within the initialize method we are setting instance variables to be used throughout the class using the parameters given. Unlike our previous example with @@name, the name "Buddy" will only refer to that instance of the Dog class, as not all dogs created are named "Buddy". If you think about it, if we are assigning these variables for this specific instance of the class in this method then self must be pointing to the instance of the class.

All Other Class Instance Methods

initialize is not our only class instance method. Any method you create within a class which is not prepended by self. is an instance method. This means that in any of those methods self refers to the instance of the class it is being called on.

Class Instance Methods Code Snippet

This is why we use buddy.play_fetch instead of Dog.play_fetch. We want Buddy, the black lab, to play fetch with a stranger not the Dog class.

Final Thoughts

We've explored a few different contexts of self in Ruby today. We've learned that within a blank .rb file, self refers to the main object. We now know that within a class and module, self refers to the class or model it is in, unless of course we are calling it within an instance method in a class, in which case it points to the instance of the class. Finally, we learned about class methods and that they refer to the class itself.

Hopefully, if you were having trouble understanding the concept of self, you have a better understanding of it now thanks to all the puppies.

Happy Coding!

Note: The cover image for this blog post is brought to you from the Sunflower Festival at Swank Farms in Hollister, CA.

Sources

Self in Ruby: A Comprehensive Overview
@/@@ vs. self in Ruby

Posted on by:

torianne02 profile

Victoria Crawford

@torianne02

["Software Engineer @ FireHydrant", "Cat Mom", "Ruby Enthusiast", "Forever Learner"]

Discussion

markdown guide
 

I find self in Ruby so much more pleasant than, say, this in JS in terms of being consistent and intuitive.

Btw great explanation.

 

I completely agree with you there and thanks 😊