一聚教程网:一个值得你收藏的教程网站

热门教程

ruby类实例变量魔法的详解

时间:2022-06-25 02:13:45 编辑:袖梨 来源:一聚教程网

学习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
类变量是私有的,在类外无法直接访问,你只能通过实例方法和类方法去访问它。

热门栏目