Learning Keyword Self in Ruby
We’re going to dive deeper into the keyword self
in Ruby. Just like other programming languages, it is a powerful tool allowing developers to contextually refer to a class or object. There are many behaviors of self
in Ruby which are dependent on the context in which it is used in. One rule that is unchanged is that self
always refers to one and only one object at a given time.
Top-Level Object
Top level context is any Ruby code that is not executing inside a sub-level code block such as class
, module
, method
, or any other sub-level code blocks. Typically it’s any naked code in a Ruby file. self
in the top-level context is an object called main
. Any execution in Ruby is within the context of an object and self
is a part of that main
object.
Class Self
self
can be referred to a class
for the context within itself when called on itself. Here we output self
in this class context:
class Player
puts "Self is: #{self}"
end
In the code above, in the class
context, self
is equivalent to the parent class
where it was defined. The keyword self
in this case can actually be thought of being a substitute for the class
:
Self is: Player
Module Self
The use of self inside a module
is similar to that of a class
definition. As seen below they are treated the same.
module Game
puts "Self inside module: #{self}" class Player
puts "Self inside module::class: #{self}"
end
end
Ruby will recognize the hierarchy of module
to class
in this case and will output the following:
Self inside module: Game
Self inside module::class: Game::Player
Class Method Self
class method
vs class instance method
- A
class method
is referred to only the class itself and not theinstance
of that class. - A
class instance method
is referred to all of theinstances
of the class and not the class itself.
Kind of confusing but to clarify, the example code below contains a class
variable company
and a getting method
:
class Player
@@name = "Bob Smith"def self.name
puts "Self in class method: #{self}"
return @@name
end
endputs "Player class method is: #{Player.name}"
The self
inside the class refers to the parent class
object and the self.name
provides functionality to one instance
of the class.
Self in class method: Player
Player class method is: Bob Smith
Class Instance Method Self
As mentioned previously, a class instance method
refers to all of the instances
of the class and not the class itself. Defining a class instance method
can be done by just excluding the self
.
class Player
def name
puts "Self inside class instance method: #{self}"
puts "Self.class inside class instance method: #{self.class}"
return "Bob Smith"
end
endplayer = Player.new
puts "Player class instance method: #{player.name}"
The instance method would have to create a new instance before calling it. The self
keyword refers to a certain instance
when in context of a class instance method
.
Self inside class instance method: #<Player:0x00000004c38c9>
Self.class instance class instance method: Player
Player class instance method: Bob Smith
Another example is shown below for the difference when calling class and instance methods
class Playerdef self.from_class
"I'm from a class method"
enddef from_instance
"I'm from an instance method"
end
end
If we call try calling these methods, it would yield:
>> Player.from_class
=> I'm from a class method>> Player.from_instance
=> undefined method 'from_instance' for Player:Class
Now if we try to create an instance for the Player
class:
>> player = Player.new>> player.from_class
=> undefined method `from_class' for #<Player:0x0000342920cds340>>> player.from_instance
=> I'm from an instance method
We cannot call an instance method on a class and we cannot directly call a class method on an instance. This can be shown below.