1.由于实变量是属于某个对象的,因此,只要对象存在,那么属于它的实变量就会一直存在。这个没什么好说的。就比如一个人是“人类”的对象,那么这个人的“大脑”(可以看作它的一个实变量)就会存在(暂且不说能不能访问到)。那么,既然已经有你这个人了,而大脑本身是属于人类对象的一个变量,那它岂有不存在之理?
2.这个要说一下变量的存在性和访问性。你要清楚变量存在性和访问性完全是两回事。就像你知道有中南海这个地方,但是你却没有机会“访问”它一样。(咳咳,和谐)上面已经说明,对象存在,那么属于它的实变量就会存在。但是这些实变量能否被访问到呢?这就不好说了。“访问”的意思你现在可以理解为读取和修改。有些实变量需要和外界访问,有些则不需要,所以我们要采用定义方法的方式对实变量进行访问。因为,普通方法是可以访问实例变量的。
于是,定义name和name=也就不难理解了。定义name的意思就是取出对象的实变量@name,而定义name=的意思就是对@name变量进行修改。
3.形式参数可以随便改。name=和name实际是两个方法名字,所以其实'name'的含义只是方便人的理解,对于机器来说是一样的。而且这两个方法名字和@name这个变量没有什么必然联系。
class Person def initialize @name = "" end def ryanbern return @name end def ryanbern=(a) @name = a end end
class Person
def initialize
@name = ""
end
def ryanbern
return @name
end
def ryanbern=(a)
@name = a
end
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改成你的参数,非常天真。
class Person def initialize @name = "Ryan" end def name return @name.upcase end def name=(name) @name += name end end alex = Person.new p alex.name #=>"RYAN" alex.name = "Bern" p alex.name #=>"RYANBERN"
class Person
def initialize
@name = "Ryan"
end
def name
return @name.upcase
end
def name=(name)
@name += name
end
end
alex = Person.new
p alex.name #=>"RYAN"
alex.name = "Bern"
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=方法。
class A attr_writer :x def initialize @x = 0 end end a = A.new a.x += 1
class A
attr_writer :x
def initialize
@x = 0
end
end
a = A.new
a.x += 1
↑以上的例子有错误(如果看不出就跑一下,会报错),请说明原因。 |