在我提出问题之前,请允许我说明我已经阅读了问题here,here和here的答案。因此,要求您不要将我的问题标记为重复,因为这些答案并不能让我理解attr_accessor
的目的。我的问题更多的是与逻辑有关,而不是语法。
我在下面创建了两组代码。这些集合彼此相同,只是一个集合没有attr_accessor
行。当我运行两组时,它们都给了我相同的输出。那么,从逻辑上讲,attr_accessor
行有什么不同,当两组代码给出了相同的预期输出时?
代码集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!
代码集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!
这两组代码都调用Animal类来创建带有名称的动物对象的新实例。我强调“......名字。”因为attr_accessor(在第二组中)定义了:name
属性。但是在第一个代码集中,我删除了attr_accessor
,但仍然设法使用name属性创建对象实例。
答案 0 :(得分:1)
attr_accessor :attribute_name
是:
def attribute_name
@attribute_name
end
def attribute_name=(value)
@attribute_name = value
end
它用于设置实例变量。在您的代码剪切中,您可以直接在initialize
方法中设置实例变量,因此您不需要attr_accessor
。
答案 1 :(得分:0)
实例变量总是可以在代码演示的实例方法中读/写。 attr_accessor
使实例变量可读/可写在类之外(通过定义访问器方法)。通过将其添加到第二个示例,您可以允许以下内容:
cat = Cat.new("Garfield")
puts cat.name
cat.name = "Maru"
会在第一个例子中引发NoMethodError
。