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?!
β¨
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
.
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
.
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.
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.
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!
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.
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
Top comments (2)
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 π