Instance variable: self vs @ Instance variable: self vs @ ruby ruby

Instance variable: self vs @


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`    endend n = Node.new(30)n.show()

will return

30nil

However, when you remove the initializer, it will return

nil30

With the class definition

class Node2    attr_accessor :value    def initialize(value)        @value = value    end    def show()        p @value        p self.value    endend

You should provide the constructor.

n2 = Node2.new(30)n2.show()

will return

3030