假设你有一个Person
。
class Person
end
person = Person.new
person.name # => no method error
显然我们从未定义方法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
啊哈,我们可以读取名称,但这并不意味着我们可以指定名称。这是两种不同的方法。前者称为读者 ,后者称为作家 。我们还没有创作作家,所以让我们这样做。
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 文档。
attr_accessor 只是一种方法 。 (该链接应提供有关其工作原理的更多信息 - 查看生成的方法对,教程应向您展示如何使用它。)
诀窍是class
不是 Ruby 中的定义 (它只是 C ++ 和 Java 等语言中的 “定义”),但它是一个评估的表达式 。在此评估期间,当调用attr_accessor
方法时,该方法又修改当前类 - 记住隐式接收器: self.attr_accessor
,其中self
是此时的 “open” 类对象。
对attr_accessor
和朋友的需求是:
与 Smalltalk 一样,Ruby 不允许在该对象的方法1之外访问实例变量。也就是说,实例变量不能以xy
形式访问,就像在 Java 甚至 Python 中常见的那样。在 Ruby 中, y
始终被视为要发送的消息(或 “要调用的方法”)。因此, attr_*
方法创建了包装器,它通过动态创建的方法代理实例@variable
访问。
锅炉很糟糕
希望这能澄清一些细节。快乐的编码。
attr_accessor
(如 @pst 所述)只是一种方法。它的作用是为您创造更多方法。
所以这里的代码如下:
class Foo
attr_accessor :bar
end
相当于这段代码:
class Foo
def bar
@bar
end
def bar=( new_value )
@bar = new_value
end
end
您可以在 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