Ruby 中的 self

self 指的是当前对象。在调用方法时,分为两个步骤,查找方法和执行方法,调用方法的对象成为接收者,也就是当前对象。没有哪个对象可以一直充当当前对象的角色,并且,任何时刻,只有一个对象充当当前对象。

一. self 的含义

1。在class关键字(类)内部,self指的是类本身。

1
2
3
4
class Myclass
puts self
end
# Myclass

2。def 定义的方法内部,self指的是调用这个方法的对象(当前对象)

1
2
3
4
5
6
7
class Myclass
def my_method
pust self
end
end
$ obj = Myclass.new #=> #<Myclass:0x007f90ee0e1830>
$ obj.method #=> #<Myclass:0x007f90ee0e1830>

3。 self写在def关键字的后面,self指的是类本身

1
2
3
4
5
6
7
8
9
10
class Myclass
def self.my_method
puts self
end
end
$ obj = Myclass.new #=> #<Myclass:0x007fe83294de88>

$ obj.my_method #=> NoMethodError: undefined method `my_method' for #<Myclass:0x007fe83294de88>

$ Myclass.my_method #=> Myclass

由此可见,当self出现在def关键字后面时,self指的是Myclass这个类,而非Myclass类的实例obj。

二. 显式self与隐式self

《ruby元编程》中提到私有规则:私有方法只能通过阴性的接收者调用。另:当一个对象被创建时,那么它就获得了它所属类中的实例方法。
1。 ruby中定义的方法不特殊说明时,默认为public方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class A
public #可省略
def method1
puts "I am method1"
self.method2
end

def method2
puts "I am method2"
end

def method3
puts "I am method3"
method2
end
end

$ obj = A.new
$ obj.method1
#=> I am method1
#=> I am method2
$ obj.method3
#=> I am method3
#=> I am method2

2。 private 定义私有方法

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
class A
public #可省略
def method1
puts "I am method1"
self.method3
end

def method2
puts "I am method2"
method3
end

private

def method3
puts "I am method3"
end
end

$ obj = A.new
$ obj.method3 #=> private method `method3' called for #<A:0x007fc1c9111f60> (NoMethodError)

$ obj.method1 #=> private method `method3' called for #<A:0x007f8f9e822230> (NoMethodError)

$ obj.method2
#=> I am method2
#=> I am method3

由此得知,调用私有方法时不能明确指定接收者是谁,也就是只有隐性的接受者才能调用私有方法。

三. 方法访问级别

1。private 与 protected

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
47
48
49
50
51
52
53
class Father

def method_a
puts "I am METHOD A in #{self.class}"
end

def method_b
puts "I am METHOD B in #{self.class}"
self.method_c #self 可以省略
end

protected
def method_c
puts "I am METHOD C in #{self.class}"
end

private
def method_secret
puts "I am method_secret in #{self.class}"
end

end


class Son < Father

def son_method_c
method_c
end

def son_method_d
self.method_c
end

def son_method_secret
self.method_secret
end

end

$ son = Son.new
$ son.son_method_c #=> I am METHOD C in Son
$ son.son_method_d #=> I am METHOD C in Son
$ son.son_method_b
#=> I am METHOD B in Father
#=> I am METHOD C in Father
$ son.method_c #=> NoMethodError: protected method `method_c' called for
$ son.method_secret #=> NoMethodError: private method `method_secret' called for
$ son.son_method_secret #=> NoMethodError: private method `method_secret' called for


$ father = Father.new
$ father.method_c #=> NoMethodError: protected method `method_c' called for

由此得知:
(1)在调用protected和private级别的方法时,不管是同类的对象(father)还是子类的对象(son),都不能够对其直接调用;只能通过其他方式,比如在别的方法中引用。
(2)ruby中的私有方法只能被阴性self调用;public方法和protected方法可被显示self和隐式self调用。