The self variable is used to represent the instance of the class which is often used in object-oriented programming. It works as a reference to the object. Python uses the self parameter to refer to instance attributes and methods of the class.
The keyword self in Ruby enables you to access to the current object — the object that is receiving the current message. The word self can be used in the definition of a class method to tell Ruby that the method is for the self, which is in this case the class.
self is a special variable that points to the object that "owns" the currently executing code. Ruby uses self everwhere: For instance variables: @myvar. For method and constant lookup. When defining methods, classes and modules.
Class variables also known as static variables are declared with the static keyword in a class, but outside a method, constructor or a block. Instance variables are created when an object is created with the use of the keyword 'new' and destroyed when the object is destroyed.
Writing @age
directly accesses the instance variable @age
. Writing self.age
tells the object to send itself the message age
, which will usually return the instance variable @age
— but could do any number of other things depending on how the age
method is implemented in a given subclass. For example, you might have a MiddleAgedSocialite class that always reports its age 10 years younger than it actually is. Or more practically, a PersistentPerson class might lazily read that data from a persistent store, cache all its persistent data in a hash.
The difference is that it is isolating the use of the method from the implementation of it. If the implementation of the property were to change -- say to keep the birthdate and then calculate age based on the difference in time between now and the birthdate -- then the code depending on the method doesn't need to change. If it used the property directly, then the change would need to propagate to other areas of the code. In this sense, using the property directly is more fragile than using the class-provided interface to it.
Be warned when you inherit a class from Struct.new
which is a neat way to generate an intializer (How to generate initializer in Ruby?)
class Node < Struct.new(:value)
def initialize(value)
@value = value
end
def show()
p @value
p self.value # or `p value`
end
end
n = Node.new(30)
n.show()
will return
30
nil
However, when you remove the initializer, it will return
nil
30
With the class definition
class Node2
attr_accessor :value
def initialize(value)
@value = value
end
def show()
p @value
p self.value
end
end
You should provide the constructor.
n2 = Node2.new(30)
n2.show()
will return
30
30
The first answer is entirely correct, but as a relative newbie it wasn't immediately clear to me what it implied (sending messages to self? uh huh...). I think that a short example will help:
class CrazyAccessors
def bar=(val)
@bar = val - 20 # sets @bar to (input - 20)
end
def bar
@bar
end
def baz=(value)
self.bar = value # goes through `bar=` method, so @bar = (50 - 20)
end
def quux=(value)
@bar = value # sets @bar directly to 50
end
end
obj = CrazyAccessors.new
obj.baz = 50
obj.bar # => 30
obj.quux = 50
obj.bar # => 50
There isn't any difference. I suspect that it was done just for the documentary value of seeing self.age
and other_person.age
near each other.
I suppose that use does allow for an actual getter to be written in the future, which might do something more complex than just return an instance variable, and in that case the method would not need to change.
But that's an unlikely abstraction to worry about, after all, if the implementation of the object changed it's reasonable to change other methods, at some point a simple reference within the object itself is perfectly reasonable.
In any case, abstraction of the age
property still doesn't explain the explicit use of self
, as just plain age
would also have invoked the accessor.
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