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


当前回答

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

其他回答

Attr_accessor非常简单:

attr_accessor :foo

是以下操作的快捷方式:

def foo=(val)
  @foo = val
end

def foo
  @foo
end

它只不过是一个对象的getter/setter

我认为让新手和程序员(比如我自己)困惑的部分原因是:

“为什么我不能告诉实例它有任何给定的属性(例如,名称),并一次性为该属性赋值?”

更一般化一点,但这就是我的想法:

考虑到:

class Person
end

我们还没有将Person定义为可以有名称或任何其他属性的东西。

那么如果我们

baby = Person.new

...试着给它们起个名字…

baby.name = "Ruth"

我们得到一个错误,因为在Rubyland中,对象的Person类不是与“名称”相关联或不具有“名称”的东西……然而!

但是我们可以使用任何给定的方法(参见前面的回答)来说明,“Person类(baby)的实例现在可以有一个名为'name'的属性,因此我们不仅有了获取和设置该名称的语法方法,而且这样做对我们来说是有意义的。”

再一次,从一个稍微不同和更一般的角度来解决这个问题,但我希望这有助于Person类的下一个实例找到这个线程的方法。

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

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

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

# the_attribute

and

# the_attribute =

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

我是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

定义此模块的命名属性,其中名称为symbol。Id2name,创建实例变量(@name)和读取它的相应访问方法。还创建一个名为name=的方法来设置属性。

module Mod
  attr_accessor(:one, :two)
end
Mod.instance_methods.sort   #=> [:one, :one=, :two, :two=]