回到Ruby系列文章
Ruby的self含义解释 在类定义中、模块定义中,可以使用self
来表示当前的对象。在不同上下文中,『当前』的概念不同:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 puts "self in Top-Level: #{self } " module M1 puts "self in M1: #{self } " def self .m puts "self in M1.m: #{self } " end def mf1 puts "self in mf1: #{self } " end class C puts "self in M1::C: #{self } " end end M1 .mclass Cls puts "self in Cls: #{self } " include M1 def f puts "self in f: #{self } " end class Cls1 puts "self in Cls1: #{self } " end end Cls .new.fCls .new.mf1
因为类上下文和模块上下文的self都代表自身(类和模块自身也是对象),所以经常见到下面两种方式定义类方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 class C def self .f1 puts "class method: f1" end class << self def f2 puts "class method: f2" end end end
在Ruby中,def x.y
和class << x
是等价的,都表示打开对象x的单例类空间,进入该单例空间的上下文。所以,上面的示例是打开C对象(类也是对象)的单例类上下文,并在单例类中定义方法f1和f2。
换句话说,Ruby中的类方法是通过类的单例类实现的 。
1 2 p C.singleton_methods()
如果打开C的单例类后,在单例类中继续使用def self.f3
来定义方法f3,因为此时的def self.
又打开了一层单例类,即C的单例类的单例类,所以方法f3定义在C的单例类的单例类中,它不再是C的类方法,而是C的单例类的类方法。如果要调用f3,需C.singleton_class.f3
:
1 2 3 4 5 6 7 8 9 class C class << self def self .f3 puts "class method: f3" end end end C.singleton_class.f3
无点引用时省略的self 在对象内部,所有『无点引用』的方式其实都是省略了self的引用 :
如果无点引用一个方法时省略了方法调用的括号(如name
),如果正好又存在一个同名局部变量name,则局部变量优先,如果此时要访问同名方法而非局部变量,则加上括号name()或self.name
如果无点引用后有一个=
,要注意它可能是在创建局部变量,而非访问setter方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class C attr_reader :name , :age def initialize name, age @name = name @age = age end def f puts "in f" puts "i am #{name} " end def g puts "in g" f end end C.new("junmajinlong" , 23 ).g