我很难理解Ruby中的attr_accessor。 有人能给我解释一下吗?
当前回答
简单地说,它将为类定义setter和getter。
请注意,
attr_reader :v is equivalant to
def v
@v
end
attr_writer :v is equivalant to
def v=(value)
@v=value
end
So
attr_accessor :v which means
attr_reader :v; attr_writer :v
等效于为类定义setter和getter。
其他回答
另一种理解它的方法是通过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是一个简单的方法,可以帮助我们清理(DRY-ing)重复的getter和setter方法。 这样我们就可以更专注于编写业务逻辑而不用担心setter和getter。
属性和访问器方法
属性是可以从对象外部访问的类组件。它们在许多其他编程语言中被称为属性。它们的值可以通过使用“点表示法”来访问,如object_name.attribute_name。与Python和其他一些语言不同,Ruby不允许从对象外部直接访问实例变量。
class Car
def initialize
@wheels = 4 # This is an instance variable
end
end
c = Car.new
c.wheels # Output: NoMethodError: undefined method `wheels' for #<Car:0x00000000d43500>
In the above example, c is an instance (object) of the Car class. We tried unsuccessfully to read the value of the wheels instance variable from outside the object. What happened is that Ruby attempted to call a method named wheels within the c object, but no such method was defined. In short, object_name.attribute_name tries to call a method named attribute_name within the object. To access the value of the wheels variable from the outside, we need to implement an instance method by that name, which will return the value of that variable when called. That's called an accessor method. In the general programming context, the usual way to access an instance variable from outside the object is to implement accessor methods, also known as getter and setter methods. A getter allows the value of a variable defined within a class to be read from the outside and a setter allows it to be written from the outside.
在下面的示例中,我们向Car类添加了getter和setter方法,以便从对象外部访问wheels变量。这不是定义getter和setter的“Ruby方式”;它只是用来说明getter和setter方法的作用。
class Car
def wheels # getter method
@wheels
end
def wheels=(val) # setter method
@wheels = val
end
end
f = Car.new
f.wheels = 4 # The setter method was invoked
f.wheels # The getter method was invoked
# Output: => 4
上面的示例可以工作,类似的代码通常用于创建其他语言中的getter和setter方法。但是,Ruby提供了一种更简单的方法:三个内置方法,分别是attr_reader、attr_writer和attr_acessor。attr_reader方法使实例变量从外部可读,attr_writer使实例变量可写,attr_acessor使实例变量可读可写。
上面的例子可以写成这样。
class Car
attr_accessor :wheels
end
f = Car.new
f.wheels = 4
f.wheels # Output: => 4
在上面的例子中,wheels属性在对象外部是可读和可写的。如果我们使用attr_reader而不是attr_accessor,它将是只读的。如果我们使用attr_writer,它将只写。这三个方法本身并不是getter和setter,但是当调用时,它们为我们创建了getter和setter方法。它们是动态(以编程方式)生成其他方法的方法;这就是所谓的元编程。
第一个(较长的)示例没有使用Ruby的内置方法,应该仅在getter和setter方法中需要额外代码时使用。例如,setter方法可能需要在将值分配给实例变量之前验证数据或进行一些计算。
通过使用instance_variable_get和instance_variable_set内置方法,可以从对象外部访问(读和写)实例变量。然而,这很少是合理的,而且通常是一个坏主意,因为绕过封装往往会造成各种破坏。
我也遇到过这个问题,并写了一篇有点冗长的回答。关于这个问题已经有了一些很好的答案,但如果有人想进一步澄清,我希望我的答案能有所帮助
初始化方法
Initialize允许您在创建实例时将数据设置为对象的实例,而不是每次创建类的新实例时都必须在代码中的单独一行中设置数据。
class Person
def initialize(name)
@name = name
end
def greeting
"Hello #{@name}"
end
end
person = Person.new("Denis")
puts person.greeting
在上面的代码中,我们使用initialize方法通过initialize中的参数传递Dennis来设置名称“Denis”。如果我们想在不使用initialize方法的情况下设置名称,可以这样做:
class Person
attr_accessor :name
# def initialize(name)
# @name = name
# end
def greeting
"Hello #{name}"
end
end
person = Person.new
person.name = "Dennis"
puts person.greeting
在上面的代码中,我们使用person.name调用attr_accessor setter方法来设置名称,而不是在初始化对象时设置值。
这两个“方法”都做这个工作,但初始化节省了我们的时间和代码行数。
这是初始化的唯一工作。不能将initialize作为方法调用。要实际获取实例对象的值,需要使用getter和setter (attr_reader (get)、attr_writer(set)和attr_accessor(两者))。请参阅下面的详细信息。
getter, Setters (attr_reader, attr_writer, attr_accessor)
getter, attr_reader: getter的全部目的是返回特定实例变量的值。请访问下面的示例代码以了解这方面的详细信息。
class Item
def initialize(item_name, quantity)
@item_name = item_name
@quantity = quantity
end
def item_name
@item_name
end
def quantity
@quantity
end
end
example = Item.new("TV",2)
puts example.item_name
puts example.quantity
在上面的代码中,您在Item“example”的实例上调用方法“item_name”和“quantity”。“举例”。Item_name和example。Quantity”将返回(或“获取”)传递到“示例”中的参数值,并将它们显示在屏幕上。
幸运的是,在Ruby中有一个固有的方法,可以让我们更简洁地编写代码;attr_reader方法。请参阅下面的代码;
class Item
attr_reader :item_name, :quantity
def initialize(item_name, quantity)
@item_name = item_name
@quantity = quantity
end
end
item = Item.new("TV",2)
puts item.item_name
puts item.quantity
这种语法的工作方式完全相同,只是它为我们节省了6行代码。想象一下,如果您有5个可归属于Item类的状态?代码很快就会变长。
Setters, attr_writer: setter方法最初让我感到困惑的是,在我看来,它执行的功能与initialize方法相同。下面我将根据我的理解来解释两者的区别;
如前所述,initialize方法允许您在对象创建时设置对象实例的值。
但是,如果您想稍后(在实例创建之后)设置这些值,或者在初始化后更改它们,该怎么办呢?这是一个使用setter方法的场景。这就是区别。在最初使用attr_writer方法时,不必“设置”特定的状态。
下面的代码是使用setter方法为Item类的这个实例声明值item_name的示例。注意,我们继续使用getter方法attr_reader,这样我们就可以获取值并将它们打印到屏幕上,以防您想自己测试代码。
class Item
attr_reader :item_name
def item_name=(str)
@item_name = (str)
end
end
下面的代码是使用attr_writer来再次缩短代码并节省时间的示例。
class Item
attr_reader :item_name
attr_writer :item_name
end
item = Item.new
puts item.item_name = "TV"
下面的代码重复了上面的初始化示例,其中我们使用initialize在创建时设置对象item_name的值。
class Item
attr_reader :item_name
def initialize(item_name)
@item_name = item_name
end
end
item = Item.new("TV")
puts item.item_name
attr_accessor:执行attr_reader和attr_writer的函数,为您节省了多一行代码。
attrr -accessor简单地为指定的属性创建getter和setter方法
推荐文章
- 在Ruby中将整数转换为十六进制字符串
- 如何记录Ruby代码?
- Ruby:包含的反义词是什么?Ruby数组?
- 在Ruby中,proc和lambda有什么区别?
- 如何传递参数到一个Rake任务与环境在Rails?
- 获取当前正在执行的方法的名称
- 如何在Rails中计算相对时间?
- 在Ruby中使用范围填充数组的正确方法
- “for”和“each”在Ruby中
- 我如何复制一个哈希在Ruby?
- Ruby/Rails:将Date转换为UNIX时间戳
- 我如何编码/解码HTML实体在Ruby?
- Ruby有一个string. startwith ("abc")内置方法吗?
- 如何从URL下载文件并保存在Rails中?
- 从字符串中移除子字符串