When you start learning Ruby, possibly one of the most confusing topics you’ll find will be the usage of self
.
More so if you have never coded before and it is the first time you stumble upon this concept.
The idea of self
as the name implies, refers to the object that’s calling the keyword. So if you are using self
inside of a class definition (not inside of a method) you are referring to the class itself.
Whenever you call self
inside of an instance method self
will refer to the instance that will call that method.
And if you call self
outside the context of a class or instance method, self will refer to the main
object that Ruby creates so that it is able to run the code.
I know, it might be confusing at first, but the best way to really understand it is to jump ahead and see some examples.
Here are the cases where you’ll find self
in a real project:
1
2
3
4
5
6
7
8
class Banana
# Class method definition
def self.my_class_method
puts "This is a class method, using self"
end
end
# Since its a class method, you call it directly on the Banana class
Banana.my_class_method # Prints: "This a class method, using self"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Apple
def initialize(name)
@name = name
end
def my_instance_method
# You’ll use self on instance methods whenever
# you need to use the actual instance that's calling the method.
puts "Current instance info: #{self}"
end
end
# Since this is an instance method, it can only be used on instances
green_apple = Apple.new("green")
green_apple.my_instance_method # Prints: "Current instance info: <Apple:MEMORY_ID @name='green'>"
You will sometimes see this syntax inside of a class class << self
and that’s just taking advantage of the way self works inside of a class
so for the next example, this: class << self
and this class << ResellerIds
would work:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class ResellerIds
class << self
def for_queue(queue)
Rails.labs_module_cache.fetch(cache_key(queue)) do
reseller_ids_for(queue)
end
end
def update_cache(queues = default_queues)
queues.each do |queue|
Rails.labs_module_cache.write(cache_key(queue), reseller_ids_for(queue),
expires_in: EXPIRATION_TIME)
end
end
def cache_key(queue)
"reseller_ids_with_unmatched_for_#{queue}"
end
end
end
# Usage of class method:
ResellerIds.for_queue(queue)
ResellerIds.cache_key(queue)
Notice that in this last example, the usage and behavior of the class method is exactly the same.
But instead of defining def self.for_queue(queue)
we are using the class << self
convention to define 3 class methods at the same time.
Let’s say you open up your irb
session to execute some code and you write this:
1
2
puts self
# Print: 'main'
This, as I mentioned before, will refer to the main
object that Ruby creates everytime it runs code for the first time outside the context of a class or method.
–
As you can see, Ruby as with all programming languages, has different idiomatic ways for us to do the same thing. The more you use the language and learn its idioms, the easier it will be for you to level up.
If you want to receive my latest essays and interesting finds subscribe to my list: