public
: 不管在哪都可以 call
private
: 必須在類別內部才可以 call,不能明確指明 recevier
,即使 self 也不行
protected
: 在 public
和 private
兩者之間,不能給外面呼叫,但在類別內,是可以自由取用(要不要加 recevier 都可以)
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
class User
def initialize
end
def public
"public"
end
def call_protected
protected
end
def call_private
private
end
def call_protected_with_recevier
self . protected
end
def call_private_with_recevier
self . private
end
protected
def protected
"protected"
end
private
def private
"private"
end
# 另一種指定方式
# protected :protected
# private :private
end
user = User . new # => #<User:0x007fa756804198>
user . public # => "public"
user . protected # NoMethodError: protected method `protected' called for #<User:0x007fa756804198>
user . private # NoMethodError: private method `private' called for #<User:0x007fa756804198>
user . call_protected # => "protected"
user . call_private # => "private"
user . call_protected_with_recevier # => "protected"
user . call_private_with_recevier # NoMethodError: private method `private' called for #<User:0x007fa756804198>
另外有個例外,如果像上面的方式將 class method
放在 private 會無效
1
2
3
4
5
6
7
8
9
10
11
class A
private
def self . b
puts 'hi'
end
end
A . b
# hi
# => nil
必須使用 self
或 private_class_method
class << self
opens up self’s singleton class, so that methods can be redefined for the current self object. This is used to define class/module (“static”) method. Only there, defining private methods really gives you private class methods.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A
class << self
private
def b
'hi'
end
end
def self . c
hello
end
private_class_method :c
end
A . b # NoMethodError: private method `b' called for A:Class
A . c # NoMethodError: private method `c' called for A:Class
一般都只會用 private
,而用 protected
的情況如以下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class User
attr_reader :name
def initialize ( name )
@name = name
end
def == ( other_user )
# 當兩個 instance 都要指名 receiver 時
self . secret == other_user . secret
end
protected
def secret
" #{ name } . #{ name . length } "
end
end
foo = User . new ( "Foo" )
bar = User . new ( "Bar" )
foo == bar # => false
參考文件