When do you use self.property_name
in Ruby?
Use self when calling a class's mutator. For example, this won't work:
class Foo
attr_writer :bar
def do_something
bar = 2
end
end
The problem is that 'bar = 2' creates a local variable named 'bar', rather than calling the method 'bar=' which was created by attr_writer. However, a little self
will fix it:
class Foo
attr_writer :bar
def do_something
self.bar = 2
end
end
self.bar = 2
calls the method bar=
, as desired.
You may also use self to call a reader with the same name as a local variable:
class Foo
attr_reader :bar
def do_something
bar = 123
puts self.bar
end
end
But it's usually better to avoid giving a local variable the same name as an accessor.
self
references the current object. This lends itself to many uses:
class A
def initialize val
@val = val
end
def method1
1 + self.method2()
end
def method2
@val*2
end
end
Here running A.new(1).method1()
will return 3
. The use of self
is optional here - the following code is equivalent:
class A
def initialize val
@val = val
end
def method1
1 + method2()
end
def method2
@val*2
end
end
self
is not redundant for this purpose though - operator overloading makes it neccessary:
class A
def initialize val
@val = val
end
def [] x
@val + x
end
def method1 y
[y] #returns an array!
end
def method2 y
self.[y] #executes the [] method
end
end
This shows how self must be used if you want to call the current object's []
method.
You can generate the methods to read and write to instance variables using attr_accessor
and co.
class A
attr_accessor :val
def initialize val
@val = val
end
def increment!
self.val += 1
end
end
Using self is redundant here because you can just reference the variable directly, eg. @val
.
Using the previous class, A.new(1).increment!
would return 2.
You can return self to provide a form of syntactical sugar known as chaining:
class A
attr_reader :val
def initialize val
@val = val
end
def increment!
@val += 1
self
end
end
Here, because we are returning the current object, methods can be chained:
A.new(1).increment!.increment!.increment!.val #returns 4
You can define class methods using self:
class A
def self.double x
x*2
end
def self.quadruple x
self.double(self.double(x))
end
end
This will enable you to call A.double(2) #= 4
and A.quadruple(2) #=8
. Note that in a class method, self
references that class because the class is the current object.
The current value of self in a particular method is set to the object that that method was called upon. Normally this uses the '.' notation. When you run some_object.some_method()
, self is bound to some_object for the duration of some_method, meaning that some_method can use self in one of the ways mentioned above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With