Max*_*yak 2292
假设你有一堂课Person.
class Person
end
person = Person.new
person.name # => no method error
Run Code Online (Sandbox Code Playgroud)
显然我们从未定义过方法name.我们这样做.
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
Run Code Online (Sandbox Code Playgroud)
啊哈,我们可以读取名称,但这并不意味着我们可以指定名称.这是两种不同的方法.前者称为读者,后者称为作家.我们还没有创作作家,所以让我们这样做.
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Dennis'
person.name # => "Dennis"
Run Code Online (Sandbox Code Playgroud)
真棒.现在我们可以@name使用reader和writer方法编写和读取实例变量.除此之外,经常这样做,为什么每次浪费时间写这些方法呢?我们可以做得更轻松.
class Person
attr_reader :name
attr_writer :name
end
Run Code Online (Sandbox Code Playgroud)
即使这样也会重复.当你想要读者和作家都只使用访问者!
class Person
attr_accessor :name
end
person = Person.new
person.name = "Dennis"
person.name # => "Dennis"
Run Code Online (Sandbox Code Playgroud)
以同样的方式工作!并猜测:@name我们的person对象中的实例变量将被设置为就像我们手动执行时一样,因此您可以在其他方法中使用它.
class Person
attr_accessor :name
def greeting
"Hello #{@name}"
end
end
person = Person.new
person.name = "Dennis"
person.greeting # => "Hello Dennis"
Run Code Online (Sandbox Code Playgroud)
而已.为了理解如何attr_reader,attr_writer以及attr_accessor方法为您实际生成方法,请阅读其他答案,书籍,ruby文档.
小智 125
attr_accessor是只是一种方法.(该链接应提供有关其工作原理的更多信息 - 查看生成的方法对,教程应向您展示如何使用它.)
诀窍是,class是不是定义在Ruby中(它是在像C++和Java语言"只是一个定义"),但它是一个用于评估表达.在此评估期间attr_accessor调用方法时,该方法又修改当前类 - 记住隐式接收器:此时self.attr_accessor此处self是"open"类对象.
对attr_accessor朋友的需求是:
与Smalltalk一样,Ruby不允许在该对象的方法1之外访问实例变量.也就是说,实例变量不能以x.yJava,甚至Python中常见的形式访问.在Ruby y中,始终将其视为要发送的消息(或"调用方法").因此,这些attr_*方法创建了包装器,它@variable通过动态创建的方法代理实例访问.
锅炉很糟糕
希望这能澄清一些细节.快乐的编码.
1这不是严格正确的,并且围绕此有一些"技术",但没有对"公共实例变量"访问的语法支持.
Phr*_*ogz 67
attr_accessor是(如@pst所述)只是一种方法.它的作用是为您创造更多方法.
所以这里的代码如下:
class Foo
attr_accessor :bar
end
Run Code Online (Sandbox Code Playgroud)
相当于这段代码:
class Foo
def bar
@bar
end
def bar=( new_value )
@bar = new_value
end
end
Run Code Online (Sandbox Code Playgroud)
您可以在Ruby中自己编写这种方法:
class Module
def var( method_name )
inst_variable_name = "@#{method_name}".to_sym
define_method method_name do
instance_variable_get inst_variable_name
end
define_method "#{method_name}=" do |new_value|
instance_variable_set inst_variable_name, new_value
end
end
end
class Foo
var :bar
end
f = Foo.new
p f.bar #=> nil
f.bar = 42
p f.bar #=> 42
Run Code Online (Sandbox Code Playgroud)
efa*_*cao 37
attr_accessor 很简单:
attr_accessor :foo
Run Code Online (Sandbox Code Playgroud)
是一个快捷方式:
def foo=(val)
@foo = val
end
def foo
@foo
end
Run Code Online (Sandbox Code Playgroud)
它只不过是一个对象的getter/setter
Tyl*_*ves 24
基本上他们伪造了可公开访问的数据属性,Ruby没有.
Chu*_*uck 17
它只是一个为实例变量定义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
Run Code Online (Sandbox Code Playgroud)
BKS*_*eon 14
以上大多数答案都使用代码.这个解释试图通过类比/故事来回答它而不使用任何:
外部各方无法访问内部中央情报局的秘密
让我们想象一个真正秘密的地方:中央情报局.除了中央情报局内部的人员,没有人知道中央情报局正在发生什么.换句话说,外部人员无法访问中央情报局的任何信息.但是因为拥有一个完全保密的组织并不是一件好事,所以某些信息可以提供给外部世界 - 当然只有CIA希望每个人都知道的事情:例如中央情报局局长,这个部门的环保程度如何所有其他政府部门等.其他信息:例如谁是伊拉克或阿富汗的秘密特工 - 这些类型的事情可能仍然是未来150年的秘密.
如果您在CIA之外,您只能访问它向公众提供的信息.或者,要使用CIA说法,您只能访问"已清除"的信息.
美国中央情报局希望向中央情报局以外的公众提供的信息称为:属性.
读写属性的含义:
在CIA的情况下,大多数属性是"只读".这意味着如果你是中情局外部的一方,你可以问: "谁是中央情报局局长?" 你会得到一个直接的答案.但是,"只读"属性无法做到的是在CIA中进行更改.例如,你不能打电话,突然决定你想让金·卡戴珊成为导演,或者你希望帕丽斯·希尔顿成为总司令.
如果属性为您提供"写入"访问权限,那么即使您在外面,也可以根据需要进行更改.否则,你唯一能做的就是阅读.
换句话说,访问者允许您对不允许外部人员进入的组织进行查询或进行更改,具体取决于访问者是读取还是写入访问者.
类中的对象可以轻松地相互访问
与类完全相同的事情以及访问其中的变量,属性和方法的能力.HTH!有任何问题,请询问,我希望我能澄清一下.
小智 13
如果您熟悉OOP概念,则必须熟悉getter和setter方法.attr_accessor在Ruby中做同样的事情.
一般方式的吸气剂和塞特犬
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Eshaan'
person.name # => "Eshaan"
Run Code Online (Sandbox Code Playgroud)
二传法
def name=(val)
@name = val
end
Run Code Online (Sandbox Code Playgroud)
吸气方法
def name
@name
end
Run Code Online (Sandbox Code Playgroud)
Ruby中的Getter和Setter方法
class Person
attr_accessor :name
end
person = Person.new
person.name = "Eshaan"
person.name # => "Eshaan"
Run Code Online (Sandbox Code Playgroud)
Jbu*_*r43 12
我也遇到了这个问题,并为这个问题写了一个冗长的答案.已经有一些很好的答案,但任何寻求更多澄清的人,我希望我的答案可以帮助
初始化方法
Initialize允许您在创建实例时将数据设置为对象的实例,而不是每次创建类的新实例时都必须在代码中的单独行上设置它们.
class Person
def initialize(name)
@name = name
end
def greeting
"Hello #{@name}"
end
end
person = Person.new("Denis")
puts person.greeting
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们使用initialize方法设置名称"Denis",方法是将Dennis传递给Initialize中的参数.如果我们想在没有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
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们通过使用person.name调用attr_accessor setter方法来设置名称,而不是在初始化对象时设置值.
执行此操作的两种"方法",但初始化节省了我们的时间和代码行.
这是初始化的唯一工作.您无法调用初始化作为方法.要实际获取实例对象的值,您需要使用getter和setter(attr_reader(get),attr_writer(set)和attr_accessor(both)).有关这些的详细信息,请参见下文.
Getters,Setters(attr_reader,attr_writer,attr_accessor)
Getters,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
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,您在Item"example"的实例上调用方法"item_name"和"quantity"."puts example.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
Run Code Online (Sandbox Code Playgroud)
这种语法的工作方式完全相同,只为它节省了六行代码.想象一下,如果你还有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
Run Code Online (Sandbox Code Playgroud)
下面的代码是使用attr_writer再次缩短代码并节省时间的示例.
class Item
attr_reader :item_name
attr_writer :item_name
end
item = Item.new
puts item.item_name = "TV"
Run Code Online (Sandbox Code Playgroud)
下面的代码重复上面的初始化示例,我们使用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
Run Code Online (Sandbox Code Playgroud)
attr_accessor:执行attr_reader和attr_writer的功能,为您节省一行代码.
Ben*_*Ben 10
我认为新Rubyists /程序员(比如我自己)困惑的一部分是:
"为什么我不能告诉它具有任何给定属性的实例(例如,名称)并且一举给出该属性一个值?"
更广泛一点,但这就是它为我点击的方式:
鉴于:
class Person
end
Run Code Online (Sandbox Code Playgroud)
我们没有将Person定义为可以具有名称或任何其他属性的东西.
那么如果我们那么:
baby = Person.new
Run Code Online (Sandbox Code Playgroud)
......并试着给他们起个名字......
baby.name = "Ruth"
Run Code Online (Sandbox Code Playgroud)
我们得到一个错误,因为在Rubyland中,Person类的对象不是与"名称"相关联或能够拥有"名称"的东西......
但是我们可以使用任何给定的方法(参见前面的答案)作为一种说法,"Person类(baby)的实例现在可以有一个名为'name'的属性,因此我们不仅有一种语法方式来获取和设置这个名称,但我们这样做是有道理的."
再次,从一个稍微不同和更一般的角度来看这个问题,但我希望这有助于下一个类人物的实例,他们找到了通往这个线程的方法.
简单地说,它将为类定义一个setter和getter.
注意
attr_reader :v is equivalant to
def v
@v
end
attr_writer :v is equivalant to
def v=(value)
@v=value
end
Run Code Online (Sandbox Code Playgroud)
所以
attr_accessor :v which means
attr_reader :v; attr_writer :v
Run Code Online (Sandbox Code Playgroud)
是等价的,为类定义一个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
Run Code Online (Sandbox Code Playgroud)
可以使用以下方法:
$ bankie = BankAccout.new("Iggy")
$ bankie
$ bankie.deposit(100)
$ bankie.withdraw(5)
Run Code Online (Sandbox Code Playgroud)
以下方法引发错误:
$ bankie.owner #undefined method `owner'...
$ bankie.balance #undefined method `balance'...
Run Code Online (Sandbox Code Playgroud)
owner从balance技术上讲,它不是方法,而是属性。BankAccount类没有def owner和def balance。如果是这样,则可以使用下面的两个命令。但是那两种方法不存在。但是,您可以访问属性,就像通过!! 访问方法一样attr_accessor。因此这个词attr_accessor。属性。存取器。它像访问方法一样访问属性。
添加attr_accessor :balance, :owner使您可以读写balance和owner“方法”。现在您可以使用后两种方法。
$ bankie.balance
$ bankie.owner
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
447879 次 |
| 最近记录: |