ruby 疑难点之—— attr_accessor attr_reader attr_writer
普通的实例变量
普通的实例变量,我们没法在 class 外面直接访问
#普通的实例变量,只能在 class 内部访问
class C1
def initialize(name)
@name = name
end
end t1 = C1.new( {'a' => 1, 'b' => 2})
puts t1.name #报错: undefined method `name' for #<Context::C1:0x0000000142cd30 @name={:a=>1, :b=>2}>
如果要想在 class 外访问实例变量,我们可以自己实现实例方法来访问
#普通的实例变量,只能在 class 内部访问
class C1
def initialize(name)
@name = name
end def name
@name
end def name=(arg)
@name=arg
end
end t1 = C1.new( {'a' => 1, 'b' => 2})
puts t1.name() #正确:调用 t1.name 方法
puts t1.name=( {'c' => 3, 'd' => 4} ) #正确:调用 t1.name= 方法
puts t1.name() #正确:{"c"=>3, "d"=>4}
其实这里的 name 和 name= 方法只是故意取名和实例变量有很像,用其它名称也一样
#普通的实例变量,只能在 class 内部访问
class C1
def initialize(name)
@name = name
end def fun1()
@name
end def fun2(arg)
@name = arg
end
end t1 = C1.new( {'a' => 1, 'b' => 2})
puts t1.fun1() #正确:调用 t1.name 方法
puts t1.fun2( {'c' => 3, 'd' => 4} ) #正确:调用 t1.name= 方法
puts t1.fun1() #正确:{"c"=>3, "d"=>4}
attr_reader :arg
attr_reader 限制实例变量 arg 在 class 外部只可读,其相当于在 class 中同时定义了一个 arg 方法
#添加一个可 read 属性,在 class 外部只可 read 该实例变量(等同于通过 instance.arg 方法),而不可对该变量赋值(相当于调用 instance.arg= 方法不存在)
#attr_reader 的限定有点类似 C 中 int const * p的作用,限定的是变量,而非变量指向的对象
class C2
attr_reader :name
def initialize(name)
@name = {'a' => 1, 'b' => 2}
end
end t2 = C2.new( {'a' => 1, 'b' => 2})
puts t2.name # 正确: {"a"=>1, "b"=>2}
puts (t2.name).delete('a') # 正确: attr_reader 保护的是变量 name ,但是变量 name 指向的对象内容是可变的
puts t2.name # 正确: {"b"=>2}
puts t2.name = {'c' => 3} # 报错: undefined method `name=' for #<Context::C2:0x000000021cdf48 @name={"b"=>2}> #为了说明隐式定义了 t2.name() 方法,下面通过方法调用的形式来访问
t2 = C2.new( {'a' => 1, 'b' => 2})
puts t2.name() # 正确: {"a"=>1, "b"=>2}
attr_writer :arg
attr_reader 限制实例变量 arg 在 class 外部只可写,其相当于在 class 中同时定义了一个 arg= 方法
#添加一个可 write 属性,在 class 外部只可 write 该实例变量
class C3
attr_writer :name
def initialize(name)
@name = name
end t3 = C3.new( {'a' => 1, 'b' => 2})
puts t3.name # 报错:undefined method `name' for #<Context::C3:0x0000000140afc8 @name={:a=>1, :b=>2}>
puts t3.name = {'c' => 3} # 正确:{"c"=>3}
puts (t3.name).delete(:c) # 报错:(没有定义方法 name,所以不能用这种方式企图获取到 name 变量指向的对象): undefined method `name' for #<Context::C3:0x000000021e9c70 @name={"c"=>3}>
attr_accessor :arg
attr_reader 限制实例变量 arg 在 class 外部只可读,其相当于在 class 中同时定义了一个 arg 和 arg= 方法
class C4
attr_accessor :name
def initialize(name)
@name = name
end
end t4 = C4.new({'a' => 1, 'b' => 2})
puts t4.name #正确:相当于调用 t4.name() 方法
puts t4.name={'c' => 3, 'd' => 4} #正确:相当于调用 t4.name=() 方法
puts t4.name #正确:{"c"=>3, "d"=>4}
#为了说明隐式定义了 t4.name() 和 t4.name=() 方法,下面通过方法调用的形式来访问
puts t4.name=( {'e' => 5, 'f' => 6} )
puts t4.name() #正确:{"e"=>5, "f"=>6}
ruby 疑难点之—— attr_accessor attr_reader attr_writer的更多相关文章
- [No000011]Ruby之attr_reader,attr_writer,attr_accessor理解&用法
(Ruby/Python/Perl) Ruby 语言与Python和Perl的一个很大区别,在于Ruby中,所有的实例变量都是在类中完全私有的,只能通过accessor 方法来进行变量访问,引用一段代 ...
- Ruby attr_reader , attr_writer, attr_accessor方法
attr_reader方法------读取实例变量 attr_writer方法------改写实例变量 attr_accessor方法-----读写实例变量 class Person attr_rea ...
- ruby 疑难点之—— yield 和 yield self
yield 所有的"方法(methods)"隐式跟上一个"块(block)"参数. 块参数也可以明确给定,形式就是在参数前面加一个"&&quo ...
- Ruby类的继承
Ruby继承的语法 class DerivedClass < BaseClass #some stuff end < 为继承符号 重写(override) 的概念 有时, 我们希望子类从父 ...
- Ruby学习-第二章
第二章 类继承,属性,类变量 1.如何声明一个子类 class Treasure < Thing 这样Thing类中的属性name,description都被Treasure继承 2.以下三种方 ...
- ruby简单的基本 3
类 Ruby一切都是对象,它包含了一个恒定.例如,可以使用.class物业查看对象的类型,你可以看一下1.class.你会发现常1类型是Fixnum,1但它是Fixnum的一个例子. Ruby本类cl ...
- Ruby入坑指南
1.1 简介 Ruby语言是由松本行弘(Matz)设计,是一门通用的.面向对象的.解释型语言. 1.2 Ruby?RUBY?ruby? 1.Ruby:用来表示编程的语言 2.ruby:是指一个计算机程 ...
- Ruby语言学习笔记
在codecademy上开始玩ruby了 1.数据类型:boolean,string,number 变量直接用即可,不用声明(“拿来主义”) 运算符:+ - * / ** % == != && ...
- Ruby菜鸟入门指南
写这篇文章的初衷源于我的伙伴们在上手Ruby过程中,表现实在是太让人拙计了.由于项目的急功近利,需要迅速入门Ruby并上手项目.所以很多开发者在实际开发过程中,不熟悉Ruby的表达方式,也会沿用其他语 ...
随机推荐
- sqlserver 中的GUID 全局唯一标识 -摘自网络
--简单实用全局唯一标识 DECLARE @myid uniqueidentifierSET @myid = NEWID()PRINT 'Value of @myid is: '+ CONVERT(v ...
- 解决IE5、IE6、IE7与W3C标准的冲突,使用(IE7.js IE8.js)兼容
如果分别用IE5.IE6.IE7浏览同一个网页,将可能出现不一样的效果. 这是它们之间对CSS的解析选择器不一样或错误和个别bug所导致.为了解决这些错误和bug. 我们不得不找到一个能平衡于它们之间 ...
- 关于ORACLE的硬解析和软解析与MySQL的查询缓存query_cache探讨
今天在项目中探讨到Oracle对于SQL语句的解析方法以及MySQL相应的处理方法: --------------------------------------------------------- ...
- 大道至简—SQLite3 使用教学
OS X自从10.4后把SQLite这套相当出名的数据库软件,放进了作业系统工具集里.OS X包装的是第三版的SQLite,又称SQLite3.这套软件有几个特色: 软件属于公共财(pu ...
- HDU 5776 sum (模拟)
sum 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5776 Description Given a sequence, you're asked ...
- HDU 5723 Abandoned country (最小生成树 + dfs)
Abandoned country 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5723 Description An abandoned coun ...
- Java线程池学习
Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...
- ListCtrl控件的使用
list contrl控件的使用 .建立基于对话框的应用程序,布置界面,设置属性. 注意添加的是listctrl控件,不是listbox控件,在控件工具箱的倒数第五行list control控件. 属 ...
- 为什么 JavaScript 中基本数据类型拥有 toString 之类方法?
在 JavaSctipt 启示录一书中,关于为什么 JS 中基本数据类型可以调用一堆对象方法.大意即指,当原始数据类型(boolean,Number.String)在调用方法时,JS 将会创建对象,以 ...
- 来自JavaScript Garden摘取
1.数字类型不能用作对象,因为javascript解析器会将点号(.)解析成浮点型(as a floating point literal),比如:2.toString();会导致语法从错误,解决方法 ...