Question

Before I expand my question, let me state that I have read the answers to the questions here, here and here. So requesting you to not mark my question as duplicate as those answers didn't make me understand the purpose of attr_accessor. My question is more to do with the logic and not the syntax.

I've created two sets of code below. The sets are identical to each other except that one set simply doesn't have the attr_accessor line. When I ran both sets, they both gave me the same output. So, logically speaking, what difference does the attr_accessor line make, when both sets of code gave me the same intended output?

Code Set 1:

class Animal 

   def initialize(name)
      @name = name
   end
end
class Cat < Animal
   def talk
     "Meaow!"
   end
end
class Dog < Animal
   def talk
     "Woof!"
   end
end

animals = [Cat.new("Flossie"), Dog.new("Clive"), Cat.new("Max")]
animals.each do |animal|
    puts animal.talk
end
#Output:
#Meaow!
#Woof!
#Meaow!

Code Set 2:

class Animal

attr_accessor :name  #this line is the only difference between the two code sets.

   def initialize(name)
      @name = name
   end
end
class Cat < Animal
   def talk
     "Meaow!"
   end
end
class Dog < Animal
   def talk
     "Woof!"
   end
end

animals = [Cat.new("Flossie"), Dog.new("Clive"), Cat.new("Max")]
animals.each do |animal|
    puts animal.talk
end
#Output:
#Meaow!
#Woof!
#Meaow!

Both sets of code call the Animal class to create new instances of animal objects WITH names. I stress on "...WITH names." because the attr_accessor (in the 2nd set) is defining the :name attribute. But in the 1st code set, I have deleted the attr_accessor but still managed to create object instances with the name attribute.

Was it helpful?

Solution 2

Instance variables can always be read/written inside instance methods, which your code demonstrates. attr_accessor makes instance variables readable/writable outside the class (by defining accessor methods). By adding it to your second example, you allow the following:

cat = Cat.new("Garfield")
puts cat.name
cat.name = "Maru"

which would raise NoMethodError in your first example.

OTHER TIPS

attr_accessor :attribute_name is shorthand for:

def attribute_name
  @attribute_name
end

def attribute_name=(value)
  @attribute_name = value
end

and it's for setting instance variable. In your code snipped, you set instance variable directly in initialize method, so you don't need attr_accessor.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top