2013-08-21 2 views
0

Прежде чем я разверну свой вопрос, позвольте мне сказать, что я прочитал ответы на вопросы here, here и here. Поэтому прошу вас не отмечать мой вопрос как дубликат, поскольку эти ответы не заставили меня понять цель attr_accessor. Мой вопрос больше связан с логикой, а не с синтаксисом.Какова цель «attr_accessor» при создании объектов в Ruby?

Я создал два набора кода ниже. Наборы идентичны друг другу, за исключением того, что один набор просто не имеет линии attr_accessor. Когда я запускал оба набора, они оба дали мне тот же результат. Итак, логично, какая разница делает линия attr_accessor, когда оба набора кода дали мне тот же предполагаемый выход?

код 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! 

Оба набора кода вызвать класс животных для создания новых экземпляров объектов животного с именами. Я подчеркиваю: «... с именами». потому что attr_accessor (во втором наборе) определяет атрибут :name. Но в первом наборе кода я удалил attr_accessor, но все же удалось создать экземпляры объектов с атрибутом name.

ответ

0

Переменные экземпляра всегда могут быть прочитаны/записаны внутри методов экземпляра, которые демонстрирует ваш код. attr_accessor делает переменные экземпляра доступными для чтения/записи за пределами класса (путем определения методов доступа). При добавлении его в свой второй пример, вы позволяете следующее:

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

которые поднимают бы NoMethodError в первом примере.

+0

Спасибо Макс, это именно то объяснение, в котором я нуждался! – Abhi

1

attr_accessor :attribute_name представляет собой сокращенный:

def attribute_name 
    @attribute_name 
end 

def attribute_name=(value) 
    @attribute_name = value 
end 

и это для установки переменного экземпляра. В коде, который был отключен, вы устанавливаете переменную экземпляра непосредственно в методе initialize, поэтому вам не нужно attr_accessor.

+0

По-прежнему может потребоваться attr_accessor, если вы хотите, чтобы переменная атрибута_имя была назначена (или изменена) снова, посредством вызова метода. – vgoff

Смежные вопросы