I am a fellow SE student at Flatiron School, and have decided to blog my coding journey. I am a novice programmer with an intense level of curiosity to learn, and always welcome any constructive criticism. Let's say - I am Baby Yoda in training, and incessantly developing my Jedi mindset.
The past three weeks, I have immersed myself in Ruby procedural programming concepts from variable and methods to data structures. We proceeded with Object-Oriented Programming (OOP). The whole week, I was struggling to grasp the use of @, @@ and self. After countless hours of irb-ing, I am more comfortable now constructing Classes and implementing @, @@ and self in Object Relationships.
Okay, we understand Class is essentially a blueprint or factory. It births instances with shared attributes and behaviors. I will be using plant to iterate my thoughts as an extension of my side interest in nurseries.
class Plant def name=(name) @name = name end def name @name end end cactus = Plant.new("Cactus") cactus.name = "Cactus"
This is my preliminary Class scope with basic reader and getter methods. "Cactus" would be an instance of Plant class.
What is @ and @@?
@ is an instance variable, and @@ is a class variable. They are capable of traversing through instance and class methods. I call this an upgraded version of local variable. Let's refine our Plant class.
class Plant @@all = [] def name=(name) @name = name end def name @name end def save @@all << self end def self.all @@all end def self.chatty_plant self.all.each do |plant| puts "I am #{@name}. Water me please!" end end end
In my earlier approach to Ruby classes, I would simply refer to @instance_variable and @@class_variable on instance and class methods. They worked, and I passed the test. As I progressed through more complex schemes, this mental modeling approach became less intuitive. What if we rename @@class_variable to @@something_else? We would have to rename every single @@class_variable. What if I misspelled @instance_variable as @instance_varyable? Would Ruby help us to catch this mistake?
The rise of self
I believe this is when we should utilize self, and construct our Ruby Classes more intuitively. Referring to @ and @@ is a literal approach, and utilizing self allows our object to operate inherently. Self refers to main, or itself, in which program functions. In instance method, self refers to the instance itself, and in class method, self refers to the class itself. Let's take a look at our first alternative approach below:
def save @@all << self end
def save self.class.all << self end
We can refactor @@all to self.class.all.
@@all == @@all
Plant.class == @@all
self.class.all == @@all
Why are we using self.class.all in lieu of @@all?
It is prudent to reify and refactor our instance or class methods as our code gradually becomes more complex. By using self.class.all, we avoid possible error syntax when renaming any class variables.
def self.chatty_plant self.all.each do |plant| puts "I am #{@name}. Water me please!" end end
def self.chatty_plant all.each do |plant| puts "I am #{name}. Water me please!" end end
Do we need self in self.all.each do?
self.chatty_plant is a class method, and self.all is also a class method. We can omit self in self.all.each do. Ruby understands self as an implicit receiver in this class method.
#{@name} vs. #{name}
If we erroneously typed #{@naame}, Ruby will look for an instance variable @naame which is non-existent.
#=> I am . Water me please!
A better approach in Ruby is to call out an instance method. If we have a typo such as #{naame} instead of #{name}, Ruby will help us to navigate the error.
#=> NameError (undefined local variable or method 'naame'..)
This self mental modeling allows better design approach as our code gets more complex attributes and behaviors in Ruby implementation.
class Plant @@all = [] def name=(name) @name = name end def name @name end def save self.class.all << self end def self.all @@all end def self.chatty_plant all.each do |plant| puts "I am #{name}. Water me please!" end end end
Keep Calm and Code On.
fentybit | GitHub | Twitter | LinkedIn
Discussion (0)