What is self ?
The topic of these posts are in reference to the Ruby language. While the concept of self
is simple, the confusion that can occur depends on the context of self
in code. Taking the time to recognize where self
is used in code can let you know if self
is referencing a class or an object.
Self in a Class Method
By definition a class method is defined by prepending self
to a method definition, as a result self
references the class.
class Person
def self.species
'Homo sapiens'
end
end
bob = Person.new
bob.species
=> NoMethodError #(undefined method `species' for #<Person:0x0000000001068d48>)
Person.species
=> "Homo sapiens"
Self in an Instance Method
Implicitly inside an Instance Method
self
is not written in the code below, but it is implied. Although not written, self
references an object defined by a class.
Per Ruby documentation, self is the “current object” and the default receiver of method calls for which no explicitly receiver is specified. In other words receiver = object, if no object is specified in the method call then self is the default object. In the example below, line 9
name
is equivalent to self.name
and bob.name
.
class Person
attr_reader :name
def initialize(name)
@name = name
end
def get_name
name
end
end
bob = Person.new('Bob')
bob.name
=> 'Bob'
bob.get_name
=> 'Bob'
Explicitly inside an Instance Method
self
is written in the code below. Just like before self
references an object defined by a class. Calling the method with self
tells Ruby we are calling a setter method and not initiating a new local variable. ie object.method = value.
class Person
attr_accessor :name
def initialize(name)
@name = name
end
def change_name(new_name)
self.name = new_name
end
end
bob = Person.new('Bob')
bob.name
=> 'Bob'
bob.change_name('Rick')
=> 'Rick'
bob.name
=> 'Rick'
What happens if we do not use self
on line 9
?
class Person
attr_accessor :name
def initialize(name)
@name = name
end
def change_name(new_name)
name = new_name
end
end
bob = Person.new('Bob')
bob.name
=> 'Bob'
bob.change_name('Rick')
=> 'Rick'
bob.name
=> 'Bob'
The object bob
's name would not change because Ruby thinks you have initialized the local variable name
and not invoked the method bob.name
.
If you know of other uses of self
or find this information conflicting please leave a comment.