为什么要使用Ruby的attr_accessor,attr_reader和attr_writer?
Ruby有这种方便易用的方法来使用像这样的键来共享实例变量
attr_accessor :var
attr_reader :var
attr_writer :var
为什么我会选择attr_reader
或attr_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_reader
和attr_writer
比手动输入它们的缩写方法更方便。 除此之外,它们提供比自己编写方法定义更好的性能。 有关更多信息,请参阅Aaron Patterson撰写的本演讲 ( PDF )中的幻灯片152。
为什么要使用Ruby的attr_accessor,attr_reader和attr_writer?相关推荐
- ruby 疑难点之—— attr_accessor attr_reader attr_writer
普通的实例变量 普通的实例变量,我们没法在 class 外面直接访问 #普通的实例变量,只能在 class 内部访问 class C1def initialize(name)@name = namee ...
- Ruby语法解释:attr_reader,attr_writer和attr_accessor
attr_reader :abc 你可以在对象的实例中用 实例名.abc 得到这个变量的值,但不能修改,它相当于 def abcreturn @abcend 顺便说一下attr_writer和attr ...
- 脱离 Rails 看 Ruby
在开始这篇文章之前,我需要澄清一些事情.首先,这不是一篇关于 Ruby on Rails 的文章.如果您希望了解 Rails,每周(甚至每小时)都有相关的文章和 blog 出现,它们都对这个令人兴奋的 ...
- 零基础学习ruby_学习Ruby:从零到英雄
零基础学习ruby "Ruby is simple in appearance, but is very complex inside, just like our human body.& ...
- 惯用过程模型_惯用的Ruby:编写漂亮的代码
惯用过程模型 Ruby is a beautiful programming language. Ruby是一种美丽的编程语言. According to Ruby's official web pa ...
- Ruby学习-第二章
第二章 类继承,属性,类变量 1.如何声明一个子类 class Treasure < Thing 这样Thing类中的属性name,description都被Treasure继承 2.以下三种方 ...
- Ruby中的类与对象(一)
一些约定: 类名首字母大写 方法名首字母小写 end在Ruby中无处不在. 声明类 class BookInStock end 创建类对象 a_book = BookInStock.new anoth ...
- Ruby 学习笔记(和 Python3 语法进行对比)
我是先接触 Python3 的,如果我自己主动来选择,可能不会再去学 Ruby(可能先入为主的思想太根深蒂固了,不过最主要的还是太懒了),然鹅由于种种原因,我还是要来看一下Ruby(真是天理难容,/大 ...
- Ruby笔记三(类、对象、属性)
class Person #initialize是初始化方法,相当于Java的构造器.参数age有一个缺省值18, #可以在任何方法内使用缺省参数,而不仅仅是initialize.如果有缺省参 ...
最新文章
- 六种方法实现CSS三栏布局
- leveldb资料整理
- P2962 [USACO09NOV]灯Lights
- day23 java的异常
- 开发工具 - Reflector
- 泰康资产:投资人才的经营之道
- Oracle 创建函数
- .gliffy文件怎么打开和gliffy的免费试用两周
- 【openGL2021版】obj模型
- uni-app 使用蓝牙打印机ESC/POS指令基础方法
- mysql 求季度产量平均值
- Android文件MD5/SHA1/SHA256校验
- 康耐视VisionPro基础教程-GigE方式 连接相机
- 小米路由器忘记管理密码后重置密码
- 卷积神经网络CNN中1×1卷积作用理解
- 游客屈指可数的人间天堂――四千美岛
- Android自定义控件系列二:自定义开关按钮(一)
- IntelliJ IDEA 2020.1发布,你要的都在这!
- 微信小程序实现点击生成随机验证码功能
- MATLAB使用:如何将其他格式的数据转换成MATLAB喜欢的“.mat”格式
热门文章
- eclipse配置tomcat,访问http://localhost:8080出现404错误
- OpenGL和D3D11中的深度模版测试
- numpy数据类型dtype转换
- Silverlight/Windows8/WPF/WP7/HTML5周学习导读(8月13日-8月19日)
- windows 2003系列之搭建域环境
- 简化版XP按装IIS5.1实录
- fedora 16 x64 安装gnustep object-c开发环境
- Generator的异步编程
- liunx 下压缩解压zip文件
- U盘安装系统时黑屏! 无法进入解决办法