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


当前回答

我是ruby的新手,不得不理解下面的奇怪之处。也许将来能帮到别人。最后,就像上面提到的,其中两个函数(def myvar, def myvar=)都隐式地访问@myvar,但是这些方法可以被局部声明覆盖。

class Foo
  attr_accessor 'myvar'
  def initialize
    @myvar = "A"
    myvar = "B"
    puts @myvar # A
    puts myvar # B - myvar declared above overrides myvar method
  end

  def test
    puts @myvar # A
    puts myvar # A - coming from myvar accessor

    myvar = "C" # local myvar overrides accessor
    puts @myvar # A
    puts myvar # C

    send "myvar=", "E" # not running "myvar =", but instead calls setter for @myvar
    puts @myvar # E
    puts myvar # C
  end
end

其他回答

它只是一个为实例变量定义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

另一种理解它的方法是通过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

我是ruby的新手,不得不理解下面的奇怪之处。也许将来能帮到别人。最后,就像上面提到的,其中两个函数(def myvar, def myvar=)都隐式地访问@myvar,但是这些方法可以被局部声明覆盖。

class Foo
  attr_accessor 'myvar'
  def initialize
    @myvar = "A"
    myvar = "B"
    puts @myvar # A
    puts myvar # B - myvar declared above overrides myvar method
  end

  def test
    puts @myvar # A
    puts myvar # A - coming from myvar accessor

    myvar = "C" # local myvar overrides accessor
    puts @myvar # A
    puts myvar # C

    send "myvar=", "E" # not running "myvar =", but instead calls setter for @myvar
    puts @myvar # E
    puts myvar # C
  end
end

假设您有一个类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文档。

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

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

外界不能接触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 !任何问题,请问,我希望我能澄清。