设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 1913|回复: 3
打印 上一主题 下一主题

[已经解决] 新手问attr_reader 问题

[复制链接]

Lv3.寻梦者

梦石
0
星屑
4169
在线时间
258 小时
注册时间
2013-10-13
帖子
815
跳转到指定楼层
1
发表于 2014-10-17 11:12:47 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
实变量属于个体对象的变量称为实变量。局部变量只有在 def ~ end 等结构内部使用时才有效,然而使用实变量的话,只要其对象存在,变量的值就会被保存。实变量一般作为对象的属性来使用。

   1,“只要其对象存在,变量的值就会被保存”是怎么理解的?

class Person  
def name
    return @name
  end
  def name=(name)
    @name = name
  end
  def hello
    print "我是" + @name
  end
end

alex = Person.new
alex.name = "艾力克斯"
alex.hello                  # => 我是艾力克斯

上面的示例是先准备 @name 实变量,使用 name、name= 方法把对象附加上 @name 实变量作为属性。

      2,“使用 name、name= 方法把对象附加上 @name 实变量作为属性”是怎么理解的?
      3,参数name可以改成a吗?name和name=的name是相同概念吗?

  attr_accessor :name

这样编写是,自动定义与 : 符号右侧名称相同的实变量对应属性的取得和注解方法。上例中是生成 @name 实变量并附加成为属性。
     4,“自动定义与 : 符号右侧名称相同的实变量对应属性的取得和注解方法”可以简化成“定义与 : 符号右侧名称相同的实变量对应属性的取得和注解的Ruby方法”吗?

在只定义属性的取得方法的情况下,一般使用 attr_reader 代替 attr_accessor。
    5, attr_reader 和 attr_accessor的含义有什么不同?

Lv4.逐梦者 (版主)

梦石
0
星屑
9532
在线时间
5073 小时
注册时间
2013-6-21
帖子
3580

开拓者贵宾剧作品鉴家

4
发表于 2014-10-17 18:01:52 | 只看该作者
继续回答。
我们拿“黑猫”来举例,说说属性和对象的关系。
RUBY 代码复制
  1. class Cat
  2.   attr_accessor :color
  3.   def initialize
  4.     [url=home.php?mod=space&uid=10453]@color[/url] = "Black"
  5.   end
  6. end

猫类有一个属性叫做“颜色color”,这个属性的值是“黑Black”。color方法和color=方法,它们执行的过程依赖于实变量@color。
我们说属性依赖于对象存在而存在,意思是和属性有关的那个实变量是存在于对象中的。实际上,对象无非就是一些实变量构成的,这些实变量中,有的单独可以用来描述“对象的特性”,我们可以认为这样的实变量有特殊的地位,因此就利用attr_accessor :使之升华为“属性”。
那么,属性本质上是方法还是变量?严格来说,属性是方法。这点从属性的机制就能看出。由于attr_accessor :和def name, def name=(name)效果相同,所以属性实际上和方法无异。因此,属于属性的标识符是name,name=这样的东西。
所以可以这样去理解:属性是依赖于一些实例变量的特殊方法。由于属性本身的可以表示有特殊的(实际)含义的实变量,因此极易把属性和实变量混为一谈。
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

梦石
0
星屑
9532
在线时间
5073 小时
注册时间
2013-6-21
帖子
3580

开拓者贵宾剧作品鉴家

3
发表于 2014-10-17 13:59:00 | 只看该作者
1.由于实变量是属于某个对象的,因此,只要对象存在,那么属于它的实变量就会一直存在。这个没什么好说的。就比如一个人是“人类”的对象,那么这个人的“大脑”(可以看作它的一个实变量)就会存在(暂且不说能不能访问到)。那么,既然已经有你这个人了,而大脑本身是属于人类对象的一个变量,那它岂有不存在之理?
2.这个要说一下变量的存在性和访问性。你要清楚变量存在性和访问性完全是两回事。就像你知道有中南海这个地方,但是你却没有机会“访问”它一样。(咳咳,和谐)上面已经说明,对象存在,那么属于它的实变量就会存在。但是这些实变量能否被访问到呢?这就不好说了。“访问”的意思你现在可以理解为读取和修改。有些实变量需要和外界访问,有些则不需要,所以我们要采用定义方法的方式对实变量进行访问。因为,普通方法是可以访问实例变量的。
于是,定义name和name=也就不难理解了。定义name的意思就是取出对象的实变量@name,而定义name=的意思就是对@name变量进行修改。
3.形式参数可以随便改。name=和name实际是两个方法名字,所以其实'name'的含义只是方便人的理解,对于机器来说是一样的。而且这两个方法名字和@name这个变量没有什么必然联系。
RUBY 代码复制
  1. class Person
  2.   def initialize
  3.     @name = ""
  4.   end
  5.   def ryanbern
  6.     return @name
  7.   end
  8.   def ryanbern=(a)
  9.     @name = a
  10.   end
  11. end

如此定义,对于一个Person类的对象alex,调用alex.ryanbern就可以得到它的@name,调用alex.ryanbern = "RyanBern"就可以修改它的@name。
不过,很少有人这么做,除非他想作死,既然方法的作用是读取或修改对应的实变量,那么为什么要定义个完全不一样的标识符来给自己找麻烦?所以,一般人还是会定义成name和name=这两个方法的。
因此,attr_Xxxx :系列便诞生了。例如,写下attr_accessor :name,就等同于做了三件事情:为对象准备@name实变量;定义朴素的name方法;定义朴素的name=方法。这样写能更方便编写程序吧。请注意写下的是“朴素的name方法”和“朴素的name=方法”,也就是说用attr_accessor :name这种方式定义的变量,只具备最简单的读取和修改功能,你调用.name方法,它就把@name拿出来给你看,你调用.name=方法,它就会把@name改成你的参数,非常天真。
RUBY 代码复制
  1. class Person
  2.   def initialize
  3.     @name = "Ryan"
  4.   end
  5.   def name
  6.     return @name.upcase
  7.   end
  8.   def name=(name)
  9.     @name += name
  10.   end
  11. end
  12.  
  13. alex = Person.new
  14. p alex.name #=>"RYAN"
  15. alex.name = "Bern"
  16. p alex.name #=>"RYANBERN"

仔细体会上面的例子,attr_accessor :遇到这样的情况就无能为力了。
4.不明白这样简化意义在什么地方。
5.attr_reader :name只做了两件事:为对象准备@name实变量;定义朴素的name方法。和attr_accessor :name相比少了一个。通常,如果你不希望从外部来修改实变量的值,就可以定义attr_reader :或者你要定义不那么朴素的'name='和朴素的'name'方法,也可以这样做。同理,attr_writer :name也只做了两件事,为对象准备@name实变量;定义朴素的name=方法。
RUBY 代码复制
  1. class A
  2.   attr_writer :x
  3.   def initialize
  4.     @x = 0
  5.   end
  6. end
  7.  
  8. a = A.new
  9. a.x += 1

↑以上的例子有错误(如果看不出就跑一下,会报错),请说明原因。

点评

斑竹真的是辛苦了,连续回答了我好几个问题了!  发表于 2014-10-17 17:39
例如:“狂战士”“黑猫”,属性 狂和黑 是依据战士和猫 而存在的。那么,手册里面的属性是说哪个 标识符?又这属性是依据哪个标识符而存在的?  发表于 2014-10-17 17:31
看了你的解释,实在是好!可是我还有疑问:手册说到attr_accessor 就说到属性,根据我理解,属性只能依据具体的事物而存在(接下去说)  发表于 2014-10-17 17:27
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

梦石
0
星屑
2315
在线时间
5539 小时
注册时间
2011-1-10
帖子
6619

青铜编剧史诗剧作家剧作品鉴家

2
发表于 2014-10-17 13:27:25 | 只看该作者
本帖最后由 H·H·Y 于 2014-10-17 13:32 编辑

attr_accessor :name
同等于
  def name
    return @name
  end
  def name=(name)
    @name = name
  end
于是在定义实例之后直接使用.name方法便可以读取到@name实例变量,同时输入.name=×可以将数值×赋值到@name,就是说attr_accessor :name允许了name的读取和写入。
attr_reader :name则设name为只读:
  def name
    return @name
  end
同等的,attr_writer则为只需要写入。
  def name=(name)
    @name = name
  end

同为脚本新人,如有错误各位大触请多多调教

评分

参与人数 2星屑 +160 收起 理由
正太君 + 60 精品文章
RyanBern + 100 我很赞同

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-24 08:45

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表