Self, the Vagabond of Ruby
A few weeks ago in my Ruby class, we were introduced to the concept of self
. This can be particularly challenging to wrap your head around, especially if you’re new to programming in general.
An important thing to understand right off the bat is that every line of code in Ruby is executed against a particular self
. A method call is always sending a message to a reciever. The self
keyword gives you access to the current object – in other words, the object that is currently recieving the message. To further illustrate, I’ve outlined a couple use cases for when you’d want to use self
.
Class Methods
Probably the most common usage of self
is when defining class methods. Using the def
keyword inside of a class will create a new instance method:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Within a class, self
refers to the current Class (in this case Vagabond
), which is itself an instance of the class Class
. I know, bear with me here. Defining a method on self
then creates a class method:
1 2 3 4 5 6 7 8 |
|
Another way you could do this is to define a method within the Class
instance itself. This uses the keyword self
to open up a new context where the Class
instance is held in self
:
1 2 3 4 5 6 7 8 9 10 |
|
Disambiguation
Another case in which self
is especially useful is when assigning a value to an object’s attributes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Although we replaced the book title with “Jitterbug Perfume”, it remained set to “Still Life With Woodpecker” – which is what we see when we call print_title
. That’s because the assignment inside replace_title
is assigned to a local variable called title
, which isn’t being used for anything. If we were to change line 5 to self.title = new_title
, then the method call would return “Jitterbug Perfume” as was expected. It’s not necessary to use self.title
explicitly inside the method print_title
, because Ruby is smart enough to know that there’s no local variable with that name and will then send self
the message title
. Remember how I mentioned that a method call always sends a message to a reciever? Well, self
can also be defined as an implicit reciever. That is, if you call a method without an explicit recieving object, the method is implicitly called on self
.