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


当前回答

它只是一个为实例变量定义getter和setter方法的方法。一个示例实现如下:

def self.attr_accessor(*names)
  names.each do |name|
    define_method(name) {instance_variable_get("@#{name}")} # This is the getter
    define_method("#{name}=") {|arg| instance_variable_set("@#{name}", arg)} # This is the setter
  end
end

其他回答

The main functionality of attr_accessor over the other ones is the capability of accessing data from other files. So you usually would have attr_reader or attr_writer but the good news is that Ruby lets you combine these two together with attr_accessor. I think of it as my to go method because it is more well rounded or versatile. Also, peep in mind that in Rails, this is eliminated because it does it for you in the back end. So in other words: you are better off using attr_acessor over the other two because you don't have to worry about being to specific, the accessor covers it all. I know this is more of a general explanation but it helped me as a beginner.

希望这对你有所帮助!

基本上,它们伪造了Ruby所不具备的公开可访问的数据属性。

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

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

好吧,想象一下:

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方法。

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

另一种理解它的方法是通过attr_accessor找出它消除了哪些错误代码。

例子:

class BankAccount    
  def initialize( account_owner )
    @owner = account_owner
    @balance = 0
  end

  def deposit( amount )
    @balance = @balance + amount
  end

  def withdraw( amount )
    @balance = @balance - amount
  end
end

有以下几种方法:

$ bankie = BankAccout.new("Iggy")
$ bankie 
$ bankie.deposit(100)
$ bankie.withdraw(5)

下面的方法会抛出错误:

$ bankie.owner     #undefined method `owner'... 
$ bankie.balance   #undefined method `balance'...

从技术上讲,Owner和balance不是一个方法,而是一个属性。BankAccount类没有def owner和def balance。如果是,那么您可以使用下面的两个命令。但这两个方法都不存在。但是,您可以访问属性,就像通过attr_accessor访问方法一样!!因此有了attr_accessor这个词。属性。访问器。它像访问方法一样访问属性。

添加attr_accessor:balance,:owner允许你读写balance和owner“method”。现在您可以使用最后两个方法。

$ bankie.balance
$ bankie.owner