我很难理解Ruby中的attr_accessor。 有人能给我解释一下吗?


当前回答

假设您有一个类Person。

class Person
end

person = Person.new
person.name # => no method error

显然,我们没有定义方法名。我们来做一下。

class Person
  def name
    @name # simply returning an instance variable @name
  end
end

person = Person.new
person.name # => nil
person.name = "Dennis" # => no method error

啊哈,我们可以读名字,但这并不意味着我们可以分配名字。这是两种不同的方法。前者称为读者,后者称为作者。我们还没有创建写入器,我们来做一下。

class Person
  def name
    @name
  end

  def name=(str)
    @name = str
  end
end

person = Person.new
person.name = 'Dennis'
person.name # => "Dennis"

太棒了。现在我们可以使用reader和writer方法写入和读取实例变量@name。不过,这是经常做的,为什么每次都浪费时间写这些方法呢?我们可以做得简单些。

class Person
  attr_reader :name
  attr_writer :name
end

即使这样也会重复。当你同时需要读取器和写入器时,只需使用访问器!

class Person
  attr_accessor :name
end

person = Person.new
person.name = "Dennis"
person.name # => "Dennis"

原理是一样的!你猜怎么着:person对象中的实例变量@name将被设置,就像我们手动设置时一样,所以你可以在其他方法中使用它。

class Person
  attr_accessor :name

  def greeting
    "Hello #{@name}"
  end
end

person = Person.new
person.name = "Dennis"
person.greeting # => "Hello Dennis"

就是这样。为了理解attr_reader, attr_writer和attr_accessor方法是如何为你生成方法的,请阅读其他答案,书籍,ruby文档。

其他回答

attrr -accessor简单地为指定的属性创建getter和setter方法

简单的解释,没有任何代码

以上大多数答案都使用代码。这个解释试图通过一个类比/故事来回答这个问题:

外界不能接触CIA内部机密

Let's imagine a really secret place: the CIA. Nobody knows what's happening in the CIA apart from the people inside the CIA. In other words, external people cannot access any information in the CIA. But because it's no good having an organisation that is completely secret, certain information is made available to the outside world - only things that the CIA wants everyone to know about of course: e.g. the Director of the CIA, how environmentally friendly this department is compared to all other government departments etc. Other information: e.g. who are its covert operatives in Iraq or Afghanistan - these types of things will probably remain a secret for the next 150 years. If you're outside the CIA you can only access the information that it has made available to the public. Or to use CIA parlance you can only access information that is "cleared". The information that the CIA wants to make available to the general public outside the CIA are called: attributes.

读写属性的含义:

In the case of the CIA, most attributes are "read only". This means if you are a party external to the CIA, you can ask: "who is the director of the CIA?" and you will get a straight answer. But what you cannot do with "read only" attributes is to make changes changes in the CIA. e.g. you cannot make a phone call and suddenly decide that you want Kim Kardashian to be the Director, or that you want Paris Hilton to be the Commander in Chief. If the attributes gave you "write" access, then you could make changes if you want to, even if you were outside. Otherwise, the only thing you can do is read. In other words accessors allow you to make inquiries, or to make changes, to organisations that otherwise do not let external people in, depending on whether the accessors are read or write accessors.

类中的对象可以很容易地相互访问

另一方面,如果你已经在中央情报局内部,那么你可以很容易地打电话给你在喀布尔的中央情报局特工,因为这些信息很容易获得,因为你已经在里面了。但如果你不在中情局之外,你根本就没有权限:你不能知道他们是谁(读权限),你也不能改变他们的任务(写权限)。

类也是如此,你可以访问其中的变量、属性和方法。HTH !任何问题,请问,我希望我能澄清。

如果你熟悉面向对象的概念,你必须熟悉getter和setter方法。 在Ruby中attr_accessor做同样的事情。

Getter和Setter的一般方式

class Person
  def name
    @name
  end

  def name=(str)
    @name = str
  end
end

person = Person.new
person.name = 'Eshaan'
person.name # => "Eshaan"

Setter方法

def name=(val)
  @name = val
end

Getter方法

def name
  @name
end

在Ruby中的Getter和Setter方法

class Person
  attr_accessor :name
end

person = Person.new
person.name = "Eshaan"
person.name # => "Eshaan"

尽管已有大量的答案,但在我看来,没有一个能解释这里涉及的实际机制。它的元编程;它利用了以下两个事实:

您可以动态地修改模块/类 模块/类声明本身就是可执行代码

好吧,想象一下:

class Nameable
  def self.named(whatvalue)
    define_method :name do whatvalue end
  end
end

我们声明了一个名为which的类方法,当用值调用时,创建一个名为name的实例方法,该实例方法返回该值。这就是元编程的部分。

现在我们将子类化这个类:

class Dog < Nameable
  named "Fido"
end

我们刚才到底做了什么?在类声明中,可执行代码执行时引用了类。因此,简单的单词named实际上是对类方法named的调用,它继承自Nameable;我们传递字符串“Fido”作为参数。

命名的类方法是做什么的?它创建一个名为name的实例方法,该方法返回该值。现在,在幕后,Dog有一个这样的方法:

def name
   "Fido"
end

不相信我?然后看这个小动作:

puts Dog.new.name #=> Fido

我为什么要告诉你这些?因为我刚才对Nameable所做的和attr_accessor对Module所做的几乎完全一样。当您使用attr_accessor时,您正在调用创建实例方法的类方法(继承自Module)。特别是,它为实例属性创建了一个getter和setter方法,实例属性的名称是您提供的参数,这样您就不必自己编写这些getter和setter方法。

属性访问器attr_accessor提供了两个免费方法。

就像在Java中,它们被称为getter和setter。

很多答案都给出了很好的例子,所以我就简单点。

# the_attribute

and

# the_attribute =

在旧的ruby文档中,#表示方法。 它还可以包含一个类名前缀… MyClass # my_method