rubyのprivateとprotectedの違いは分かりにくい
- 2012/09/27 (Thu) |
- ruby |
- CM(0) |
- Edit |
- ▲Top
C++やJava、あるいはPHPといった言語から見ると、Rubyのprivate/protectedの考え方は少し違うので分かりにくい。
まずRubyの場合、スーパークラス(基底クラス)privateメソッドをサブクラス(派生クラス)のメソッド内から呼び出すことができる。この時点でC++といった言語とは違う。C++では基底クラスのprivateメンバ/メンバ関数を派生クラス側で呼び出すことはできない。(はず)
このためこの特徴からだけではRubyのprivate/protectedメソッドのアクセス制限の違いが判断できない。
次に同じクラスのインスタンスを引数に取るメソッド内で、selfとは異なるインスタンスではあるが、同じクラスから生成されたオブジェクトのメソッド呼び出しについてはどうか。
結論から言うと、ここの部分でRubyのprivate/protectedの違いがある。他インスタンスのprivateメソッドはインスタンス外部から呼び出すことができないのに対し、他インスタンスのprotectedメソッドは呼び出しが可能となる。
以下はこの動作を確認するコード。
【実行結果】
invoked method pubm(public in class A)
invoked method pm(private in class A)
invoked method use_pm2(public in class A)
invoked method prom(protected in class A)
invoked method use_pm1(protected in class A)
invoked method use_prom(public in class A)
invoked method pm(private in class A)
invoked method use_pm_b(public in class B)
invoked method prom(protected in class A)
invoked method use_pm1(protected in class A)
invoked method use_prom_b(public in class B)
invoked method prom(protected in class A)
invoked method pubm(public in class A)
invoked method show_other(public in class B)
まずRubyの場合、スーパークラス(基底クラス)privateメソッドをサブクラス(派生クラス)のメソッド内から呼び出すことができる。この時点でC++といった言語とは違う。C++では基底クラスのprivateメンバ/メンバ関数を派生クラス側で呼び出すことはできない。(はず)
このためこの特徴からだけではRubyのprivate/protectedメソッドのアクセス制限の違いが判断できない。
次に同じクラスのインスタンスを引数に取るメソッド内で、selfとは異なるインスタンスではあるが、同じクラスから生成されたオブジェクトのメソッド呼び出しについてはどうか。
結論から言うと、ここの部分でRubyのprivate/protectedの違いがある。他インスタンスのprivateメソッドはインスタンス外部から呼び出すことができないのに対し、他インスタンスのprotectedメソッドは呼び出しが可能となる。
以下はこの動作を確認するコード。
class A
private
def pm
puts "invoked method pm(private in class A)"
end
protected
def prom
puts "invoked method prom(protected in class A)"
end
def use_pm1
puts "invoked method use_pm1(protected in class A)"
end
public
def pubm
puts "invoked method pubm(public in class A)"
end
def use_pm2
pm
puts "invoked method use_pm2(public in class A)"
end
def use_prom
self.prom
self.use_pm1
puts "invoked method use_prom(public in class A)"
end
end
class B < A
def use_pm_b
pm
puts "invoked method use_pm_b(public in class B)"
end
def use_prom_b
prom
use_pm1
puts "invoked method use_prom_b(public in class B)"
end
def show_other(other)
# other.pm #can't invoke other object's private method
other.prom
other.pubm
puts "invoked method show_other(public in class B)"
end
end
#--------------------------------------------
a = A.new
#a.pm # => NoMethod Error
#a.prom # => NoMethod Error
#a.use_pm1 # => NoMethod Error
a.pubm
a.use_pm2
a.use_prom
b = B.new
b.use_pm_b
b.use_prom_b
b2 = B.new
b2.show_other(b)
【実行結果】
invoked method pubm(public in class A)
invoked method pm(private in class A)
invoked method use_pm2(public in class A)
invoked method prom(protected in class A)
invoked method use_pm1(protected in class A)
invoked method use_prom(public in class A)
invoked method pm(private in class A)
invoked method use_pm_b(public in class B)
invoked method prom(protected in class A)
invoked method use_pm1(protected in class A)
invoked method use_prom_b(public in class B)
invoked method prom(protected in class A)
invoked method pubm(public in class A)
invoked method show_other(public in class B)
PR
カレンダー
フリーエリア
最新CM
最新記事
(06/05)
(06/04)
(06/04)
(11/18)
(11/18)
ブログ内検索
最古記事
(09/15)
(09/20)
(09/27)
(09/27)
(10/11)
COMMENT