为什么要使用Ruby的attr_accessor,attr_reader和attr_writer?

Ruby有这种方便易用的方法来使用像这样的键来共享实例变量

attr_accessor :var
attr_reader :var
attr_writer :var

为什么我会选择attr_readerattr_writer如果我可以简单地使用attr_accessor ? 有没有像表演(我怀疑)? 我想有一个原因,否则他们就不会有这样的钥匙。


#1楼

重要的是要理解访问者限制对变量的访问,而不是对其内容的访问。 在ruby中,与其他一些OO语言一样,每个变量都是指向实例的指针。 因此,例如,如果您具有Hash的属性,并且将其设置为“只读”,则始终可以更改其内容,但不能更改指针的内容。 看这个:

irb(main):024:0> class A
irb(main):025:1> attr_reader :a
irb(main):026:1> def initialize
irb(main):027:2> @a = {a:1, b:2}
irb(main):028:2> end
irb(main):029:1> end
=> :initialize
irb(main):030:0> a = A.new
=> #<A:0x007ffc5a10fe88 @a={:a=>1, :b=>2}>
irb(main):031:0> a.a
=> {:a=>1, :b=>2}
irb(main):032:0> a.a.delete(:b)
=> 2
irb(main):033:0> a.a
=> {:a=>1}
irb(main):034:0> a.a = {}
NoMethodError: undefined method `a=' for #<A:0x007ffc5a10fe88 @a={:a=>1}>
        from (irb):34
        from /usr/local/bin/irb:11:in `<main>'

正如您所看到的那样,可以从Hash @a中删除一个键/值对,作为添加新键,更改值,eccetera。 但是你不能指向一个新对象,因为它是一个只读的实例变量。


#2楼

您并不总是希望可以从类外部完全访问您的实例变量。 有很多情况允许对实例变量进行读访问是有意义的,但写入它可能不会(例如,从只读源检索数据的模型)。 在某些情况下,你想要相反,但我想不出任何不做的事情。


#3楼

您可以使用不同的访问器将您的意图传达给阅读代码的人,并且无论他们如何调用公共API,都可以更轻松地编写能够正常工作的类。

class Person
  attr_accessor :age
  ...
end

在这里,我可以看到我可以读写年龄。

class Person
  attr_reader :age
  ...
end

在这里,我可以看到我可能只阅读年龄。 想象一下,它是由这个类的构造函数设置的,之后保持不变。 如果有一个年龄的mutator(作者),并且该类被写成假设年龄,一旦设置,不会改变,那么代码调用该mutator会导致错误。

但是幕后发生了什么?

如果你写:

attr_writer :age

这被翻译成:

def age=(value)
  @age = value
end

如果你写:

attr_reader :age

这被翻译成:

def age
  @age
end

如果你写:

attr_accessor :age

这被翻译成:

def age=(value)
  @age = value
end

def age
  @age
end

知道了,这是考虑它的另一种方式:如果你没有attr _...帮助器,并且必须自己编写访问器,你会编写比你需要的更多的访问器吗? 例如,如果只需要读取年龄,您是否还会编写一个允许它写入的方法?


#4楼

并非所有对象的属性都是从类外部直接设置的。 拥有所有实例变量的编写器通常是弱封装的标志,并警告您在类之间引入了过多的耦合。

作为一个实际例子:我编写了一个设计程序,您可以将项目放在容器中。 该项目有attr_reader :container ,但提供一个attr_reader :container是没有意义的,因为该项目的容器应该更改的唯一时间是它被放置在一个新的时间,这也需要定位信息。


#5楼

以上所有答案都是正确的; attr_readerattr_writer比手动输入它们的缩写方法更方便。 除此之外,它们提供比自己编写方法定义更好的性能。 有关更多信息,请参阅Aaron Patterson撰写的本演讲PDF )中的幻灯片152。

发布了0 篇原创文章 · 获赞 1 · 访问量 4945
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览