Ruby中的访问器?
我很难理解Ruby中的attr_accessor
。 谁可以给我解释一下这个?
假设你有一个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"
真棒。 现在我们可以使用读写器方法编写和读取实例变量@name
。 除此之外,经常这样做,为什么每次都浪费时间写这些方法呢? 我们可以做得更轻松。
class Person
attr_reader :name
attr_writer :name
end
即使这可能会重复。 当你想让读写器都使用accessor!
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
和朋友的需求,很好:
Ruby和Smalltalk一样,不允许在该对象的methods1之外访问实例变量。 也就是说,实例变量无法以xy
格式访问,就像在Java或甚至Python中常见的那样。 在Ruby中, y
总是作为一个消息发送(或“调用方法”)。 因此, attr_*
方法通过动态创建的方法创建代理实例@variable
访问的包装器。
锅板很烂
希望能够澄清一些小的细节。 快乐的编码。
1这并非严格意义上的,这里有一些“技巧”,但是没有对“公共实例变量”访问的语法支持。
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
链接地址: http://www.djcxy.com/p/645.html
上一篇: accessor in Ruby?
下一篇: How to get a password from a shell script without echoing