Ruby, the self keyword
What is self in Ruby
self
is a reserved keyword in Ruby that always refers to the current object and classes are also objects, but the object self
refers to frequently changes based on the situation or context. So if you’re in an instance, self
refers to the instance. If you’re in a class, self
refers to that class.
self refers to the context
Yes, the context is where your code is at any given moment.
If your code is inside an instance method, self
is an instance of that class. In other words, self
is an object.
Let’s try that, and output self
. In order to do that we need to add it somewhere inside the object. Any method would be good for that.
1
2
3
4
5
def name
puts self
end
name
# => main
This code defines and calls a .name
method which prints the value of self.
self
is initially set to main
, an instance of the Object class that is automatically created whenever a Ruby program is interpreted.
The main object is the “top-level” namespace of the program.
No matter which context the code finds itself, one important rule about self
must be remembered: self
always refers to one and only one object at any given time.
As seen here:
1
2
3
4
5
6
class Person
def name
puts self end
end
Person.new.name
#<Person:0x000056198a868c98>
From these examples, we can tell that the value of self
changes depending on where you use it.
I believe you can understand anything better by understanding its purpose.
Let’s look at some examples.
Self, inside a Class definition
In a class definition (but not in an instance method), the self
keyword refers to the class itself.
Here we have Person
class, inside which we are outputting the value of self
:
1
2
3
4
class Person
puts self
end
# => Person (the Person class)
The result is that, directly inside the context of a class definition, self
is equivalent to the parent class in which it was defined; Person
, in this case.
In singleton methods, the self
keyword also refers to the class itself.
1
2
3
4
5
6
7
class Person
def self.name
puts self
end
end
Person.name
# => Person
Why we use self
in method definition?
Let’s look at more common use case… Defining class methods !
Class-Level Methods
I’m sure you have seen it in above example. These def self.method_name
method definitions.
Because we don’t have to use the class name for each method definition, making our code easier to change if we change the class.
That’s why we do def self.name
instead of def Person.name
.
Another more advanced way to do this is to define a method inside the Class instance itself.
This is referred to as the eigenclass or the singleton class and it uses the self
keyword to open a new context where the Class instance is held in self.
Let’s check with an example.
1
2
3
4
5
6
7
8
9
class Person
class << self
def name
puts "Jane"
end
end
end
Person.name
# => "Jane"
Instance method : self
An instance method is a method that applies to all instances of that class, but not for the class object itself.
In Ruby, defining a class instance method is as simple as excluding the self
. Object prefix within the method definition; in this case, using just def name
does the trick:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Person
def name
puts "self inside method is: #{self}"
puts "self.class is: #{self.class}"
return "Jane"
end
end
# Define instance
person = Person.new
person.name
# => self inside method is: #<Person:0x000000010c38be10>
# => self.class is: Person
# => "Jane"
Since this is an instance method, we can’t call it until we create a new instance of our Person
class. After that, once we call the name method on that instance, we get the full output.
Unlike a direct class method reference to self, an instance method reference to self actually points to the particular instance that is being executed, thus our output shows an instance of the Person
class, as indicated by its memory address:
1
# => self inside method is: #<Person:0x000000010c38be10>
Self, inside a Module definition
The use of self
inside a module definition is very similar to that of a class definition
. In fact, as far as Ruby is concerned, the reference to self
doesn’t care whether you are in the context of a class, or a module, it will treat both basically the same. For example, here we are enclosed our Person
class inside the Type
module, then output the value of selfwithin both contexts:
1
2
3
4
5
6
module Type
puts "Self inside Type is: #{self}"
class Person
puts "Self inside Type::Person is: #{self}"
end
end
While Ruby treats the module definition call to self
just as it did with the class definition, representing the parent level object of Type in this case, for the child call it recognizes that there’s a hierarchy here, so we get the module plus the class:
1
2
Self inside Type is: Type
Self inside Type::Person is: Type::Person
How self
work when it not use with instance variable and method
When a method is called without an explicit self
, the implicit self
is used, which is the value of the self
keyword. In the following example, the Person#name
method uses the value from Person#first_name
and Person#last_name
, but does not explicitly use self
and relies on the value of the implicit self
.
1
2
3
4
5
6
7
8
9
10
11
12
class Person
attr_reader :first_name, :last_name
def initialize(first_name, last_name)
@first_name = first_name @last_name = last_name
end
def name
"#{first_name} #{last_name}"
end
end
Relying on the implicit self
can save quite a bit of typing over time and is very common among Ruby programmers.
Summary
self
is a keyword in Ruby representing the default object of the current context.self
is the default receiver of messages and the owner of instance variables.- Three rules for determining
self
: 1) when the current context is outside of any class/module/method definition,self
is main; 2) when the current context is inside a class/module definition and outside of method definitions,self
is the class/module; 3) when the current context is inside a method definition,self
is the receiver of the method, the object before dot(.).