学习ruby类相关的语法遇到的关于类相关变量的一点小体会。
ruby很灵活,语法看似很随意,比如看下下面的代码
class Foo
attr_accessor :name
def initialize
@name = '小明'
end
def say
puts @name
puts self.name
puts name
end
end
Foo.new.say
执行这些代码将得到如下输出:
小明
小明
小明
initialize是构造函数,在
Foo.new
的时候自动执行,
@name
是实例变量,那么在
say
方法中
puts @name
很好理解,就是打印实例变量
@name
。
puts self.name
怎么理解呢?
首先,self代表什么?它跟php的
$this
意义差不多,代表的是这个实例,在类方法中使用。
那
self.name
是表示一个类变量吗?不是的。
其实这是一个方法,若要写出来则是:
def name
return @name
end
很神奇不是吗?那如果你奇怪这个方法哪来的,那你应该注意到第二行的一句代码
attr_accessor :name
是的,
attr_accessor :name
这也是一个方法,等于是
attr_accessor(:name)
因为在ruby中括号是可以省略的,初学时可能阅读代码比较别扭。
:name
是一个符号,
attr_accessor
方法根据它来决定为
@name
实例变量创建
name
和
name=
等相关方法,即可实现在类外部通过表达式直接对实例变量赋值,如:
foo = Foo.new
foo.name = '小李' #name和=之间的空格会忽略,ruby忽略空格
puts foo.name
self.name
说明白了,那么再来看看最后一项
puts name
这是什么,这里的
name
应当怎么理解。
其实很好理解,因为ruby中调用方法可以省略括号,所以当你看到一个变量时,它可能是局部变量,也可能是方法,优先级嘛,当然是先局部变量。
我们看到
say
方法中没有定义局部变量,所以这里的
name
就当是方法了,等于是
name()
其实加上关键字self也一样
self.name()
。
越来越感慨ruby的灵活多变了,当然我还是觉得应当遵循一定的规范,不然你写的代码别人可能根本无法看懂。
我来写项目的话,在类方法内部我肯定是直接通过
@name
操作,而不会用
self.name
或
name
去做,你觉得呢?
以@开始的变量是【实例变量】,实例变量属于特定的对象。
class Person
def initialize(name, gender, age)
@name = name
@gender = gender
@age = age
end
end
上面的例子中,@name, @gender,@age都是实例变量。可以在类或子类的方法中引用实例变量。若引用尚未被初始化的实例变量的话,其值为nil。
【类变量】被一个类的所有实例对象共享,也可以被类方法访问到。类变量名以‘@@’,开始,例如‘@@number’。和全局变量,实例变量不同,类变量在使用前必须初始化:
class Person
@@number = 0 #使用前必须有初值
def initialize(name, gender, age)
@name = name
@gender = gender
@age = age
@@number += 1
end
end
类变量是私有的,在类外无法直接访问,你只能通过实例方法和类方法去访问它。