关于类:’attr_accessor’在Ruby中创建对象的目的是什么?

What's the purpose of the 'attr_accessor' in creating objects in Ruby?

本问题已经有最佳答案,请猛点这里访问。

在我展开我的问题之前,让我声明我已经在这里、这里和这里阅读了问题的答案。因此,要求你不要把我的问题标记为重复的答案,这并不能使我理解attr_accessor的目的。我的问题更多的是逻辑而不是语法。

我在下面创建了两组代码。这些集合是相同的,除了一个集合没有attr_accessor行。当我运行这两组时,它们都给了我相同的输出。所以,从逻辑上讲,当两组代码给出相同的预期输出时,attr_accessor行有什么区别?

代码集1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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类来创建具有名称的动物对象的新实例。我强调"…with names.",因为attr_访问器(在第二组中)正在定义:name属性。但是在第一个代码集中,我删除了attr_accessor,但仍然设法创建了具有name属性的对象实例。


attr_accessor :attribute_name的缩写是:

1
2
3
4
5
6
7
def attribute_name
  @attribute_name
end

def attribute_name=(value)
  @attribute_name = value
end

用于设置实例变量。在截取的代码中,直接在initialize方法中设置实例变量,这样就不需要attr_accessor了。


实例变量总是可以在实例方法中读/写,这是您的代码所演示的。attr_accessor使实例变量在类外可读/可写(通过定义访问器方法)。通过将其添加到第二个示例中,可以允许以下操作:

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

在你的第一个例子中,这会提高NoMethodError