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):34from /usr/local/bin/irb:11:in `<main>'

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


#2楼

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


#3楼

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

class Personattr_accessor :age...
end

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

class Personattr_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
enddef age@age
end

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


#4楼

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

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


#5楼

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

为什么要使用Ruby的attr_accessor,attr_reader和attr_writer?相关推荐

  1. ruby 疑难点之—— attr_accessor attr_reader attr_writer

    普通的实例变量 普通的实例变量,我们没法在 class 外面直接访问 #普通的实例变量,只能在 class 内部访问 class C1def initialize(name)@name = namee ...

  2. Ruby语法解释:attr_reader,attr_writer和attr_accessor

    attr_reader :abc 你可以在对象的实例中用 实例名.abc 得到这个变量的值,但不能修改,它相当于 def abcreturn @abcend 顺便说一下attr_writer和attr ...

  3. 脱离 Rails 看 Ruby

    在开始这篇文章之前,我需要澄清一些事情.首先,这不是一篇关于 Ruby on Rails 的文章.如果您希望了解 Rails,每周(甚至每小时)都有相关的文章和 blog 出现,它们都对这个令人兴奋的 ...

  4. 零基础学习ruby_学习Ruby:从零到英雄

    零基础学习ruby "Ruby is simple in appearance, but is very complex inside, just like our human body.& ...

  5. 惯用过程模型_惯用的Ruby:编写漂亮的代码

    惯用过程模型 Ruby is a beautiful programming language. Ruby是一种美丽的编程语言. According to Ruby's official web pa ...

  6. Ruby学习-第二章

    第二章 类继承,属性,类变量 1.如何声明一个子类 class Treasure < Thing 这样Thing类中的属性name,description都被Treasure继承 2.以下三种方 ...

  7. Ruby中的类与对象(一)

    一些约定: 类名首字母大写 方法名首字母小写 end在Ruby中无处不在. 声明类 class BookInStock end 创建类对象 a_book = BookInStock.new anoth ...

  8. Ruby 学习笔记(和 Python3 语法进行对比)

    我是先接触 Python3 的,如果我自己主动来选择,可能不会再去学 Ruby(可能先入为主的思想太根深蒂固了,不过最主要的还是太懒了),然鹅由于种种原因,我还是要来看一下Ruby(真是天理难容,/大 ...

  9. Ruby笔记三(类、对象、属性)

    class Person   #initialize是初始化方法,相当于Java的构造器.参数age有一个缺省值18,   #可以在任何方法内使用缺省参数,而不仅仅是initialize.如果有缺省参 ...

最新文章

  1. 六种方法实现CSS三栏布局
  2. leveldb资料整理
  3. P2962 [USACO09NOV]灯Lights
  4. day23 java的异常
  5. 开发工具 - Reflector
  6. 泰康资产:投资人才的经营之道
  7. Oracle 创建函数
  8. .gliffy文件怎么打开和gliffy的免费试用两周
  9. 【openGL2021版】obj模型
  10. uni-app 使用蓝牙打印机ESC/POS指令基础方法
  11. mysql 求季度产量平均值
  12. Android文件MD5/SHA1/SHA256校验
  13. 康耐视VisionPro基础教程-GigE方式 连接相机
  14. 小米路由器忘记管理密码后重置密码
  15. 卷积神经网络CNN中1×1卷积作用理解
  16. 游客屈指可数的人间天堂――四千美岛
  17. Android自定义控件系列二:自定义开关按钮(一)
  18. IntelliJ IDEA 2020.1发布,你要的都在这!
  19. 微信小程序实现点击生成随机验证码功能
  20. MATLAB使用:如何将其他格式的数据转换成MATLAB喜欢的“.mat”格式

热门文章

  1. eclipse配置tomcat,访问http://localhost:8080出现404错误
  2. OpenGL和D3D11中的深度模版测试
  3. numpy数据类型dtype转换
  4. Silverlight/Windows8/WPF/WP7/HTML5周学习导读(8月13日-8月19日)
  5. windows 2003系列之搭建域环境
  6. 简化版XP按装IIS5.1实录
  7. fedora 16 x64 安装gnustep object-c开发环境
  8. Generator的异步编程
  9. liunx 下压缩解压zip文件
  10. U盘安装系统时黑屏! 无法进入解决办法