What’s self?
Ruby newcomers usually are confused about the use of self
, whether it’s a completely new concept for them or not.
First, let’s define self:
self is the current object
The definition may seem a little too dry, but that’s exactly what self is. In your code, at any time, there’s always a self
object, and its value depends on the code context.
IRB and self
When practicing with ruby, irb is your best friend. For those who want to get fancy you can replace it with pry. Let’s see some examples, first start the irb session with the irb
command, then let’s see what irb has to say about self
:
$ irb
2.1.0 :001 > self
=> main
> self.inspect
=> "main"
self.class
=> Object
There’s always a self
when executing ruby code: at startup irb creates a top level object called main, which is actually just an instance of the Object class. That’s your default self
.
self at class definition
Time to move on. Let’s see what self
is when defining a class:
class Person
self
end
=> Person
It’s the class itself, and it makes perfect sense. Do you know about class methods? When you’re out of the context of the class, you can define them like this:
def Person.show_self
self.inspect
end
Person.show_self
=> "Person"
But when you’re in the context of the class, you can define class methods in both these ways:
class Person
def Person.show_self
self.inspect
end
def self.show_self
self.inspect
end
end
Person.show_self
=> "Person"
They are equivalent, but the latter is preferable. Why? Because if you decide to change the name of the class, you don’t have to change the name in the signature method as well.
self in instance methods
What about instance methods? Inside instance method definitions, self
is the actual instance:
class Person
def show_self
self.inspect
end
end
Person.new.show_self
=> #<Person:0x00000101939098>
Most of the times, inside method body definitions, self
is redundant and we can avoid it:
class Person
def self.show_self # class method, self is the class
inspect
end
def show_self # instance method, self is the instance
inspect
end
end
Person.show_self
=> "Person"
Person.new.show_self
=> #<Person:0x00000101939098>
When self is required
There are some cases when you need an explicit self
, namely when inside the method body there’s a local variable with the same name of the method you’re willing to call on self
. If you omit self
you’re going get some unexpected results for sure:
class Person
def show_self
inspect = 'boo!'
inspect
end
end
Person.new.show_self
=> "boo!"
class Person
def show_self
inspect = 'boo!'
self.inspect
end
end
Person.new.show_self
=> #<Person:0x00000101939098>
Another very common scenario when self
is always required is when using writer methods:
class Person
attr_accessor :name
def set_name(person_name)
self.name = person_name
end
end
me = Person.new
me.set_name 'Andrea'
me.name
=> "Andrea"
If we had written
def set_name(person_name)
name = person_name
end
then the code would have created a local variable named name.
The last important case when self
is required is when you call the class
method of an instance:
class Person
def show_class
self.class
end
end
Person.new.show_class
=> Person
In this case self is required because class is a reserved keyword, so we need to make sure the parser undestands we’re referencing to the instance class object.
When self cannot be used
Sometimes on the other hand you cannot use the explicit self
: that’s the case with private methods:
class Person
attr_accessor :name
private :name
def show_name
name
end
def buggy_show_name
self.name
end
end
me.show_name
=> "Andrea"
me.name
NoMethodError: private method `name' called for #<Person:0x00000101939098& @name="Andrea">
me.buggy_show_name
NoMethodError: private method `name' called for #<Person:0x00000101939098& @name="Andrea">
Wrapping up
In order to write idiomatic ruby, the rule of thumb is to avoid the explicit self whenever it’s not required.
Leave a Reply