ruby three Ps 実験 その1
ここまで読んでも全然わかんない orz
http://d.hatena.ne.jp/toshi_hirasawa/20130122/1358841378
よって、実験することにする
[hirasawa@centos-hira ~]$ cat threePs.rb #!/usr/local/bin/ruby -Ku class AccessTest public def publ p(self) puts "public_method" self.prot #self.priv # error!! prot priv end protected def prot p(self) puts "protected_method" end private def priv p(self) puts "private_method" end end class SubAccessTest < AccessTest def publ_s publ end def prot_s prot end def priv_s priv end end at = SubAccessTest.new() at.publ #at.prot # error! prptected method "prot" called for #<SubAccessTest:xxxx> #at.priv # error! private method "priv" called fof #<SubAccessTest:xxxx> sat = SubAccessTest.new() sat.publ_s sat.prot_s # no error! sat.priv_s # no error!
結果を以下にしめす
[hirasawa@centos-hira ~]$ ./threePs.rb #<SubAccessTest:0x9fbf4c4> public_method #<SubAccessTest:0x9fbf4c4> protected_method #<SubAccessTest:0x9fbf4c4> protected_method #<SubAccessTest:0x9fbf4c4> private_method #<SubAccessTest:0x9fbf3fc> public_method #<SubAccessTest:0x9fbf3fc> protected_method #<SubAccessTest:0x9fbf3fc> protected_method #<SubAccessTest:0x9fbf3fc> private_method #<SubAccessTest:0x9fbf3fc> protected_method #<SubAccessTest:0x9fbf3fc> private_method [hirasawa@centos-hira ~]$
まずは、private/protectedのみにターゲットを絞ってもうちょい突っ込んで確認。
つぎのコードをベースに実験
[hirasawa@centos-hira ~]$ cat private.rb #!/usr/local/bin/ruby -Ku class Main #protected ################################# #private ################################# def priv puts "private_method" end public def call_priv_from_main self.priv end def show p "show part in main" end end class Sub < Main def call_priv_from_sub self.priv end def show p "show part in sub" end end Main.new().show Sub.new().show Main.new().call_priv_from_main Sub.new().call_priv_from_sub Sub.new().call_priv_from_main [hirasawa@centos-hira ~]$ [hirasawa@centos-hira ~]$ ./private.rb "show part in main" "show part in sub" private_method private_method private_method [hirasawa@centos-hira ~]$
最初はprotectedもprivateもコメントアウトされている状態(つまりpublic)
なのでふつうに動く
つづいて、#protectedの コメントだけをはずしてみると
これも動く
最後に #privateのコメントだけを外してみると
[hirasawa@centos-hira ~]$ ./private.rb "show part in main" "show part in sub" ./private.rb:11:in `call_priv_from_main': private method `priv' called for #<Main:0xa1498a8> (NoMethodError) from ./private.rb:30:in `<main>' [hirasawa@centos-hira ~]$
ほほう、
ここまでわかったことのまとめ
- public
そのメソッドが定義されたクラス内、サブクラス、クラス外(インスタンス)のどこからでもアクセス可
public に設定されたメソッドは制限なしに呼び出し可
- private
メソッドは、クラスの内部(定義クラスとサブクラス)からのみアクセス可
レシーバを指定して呼び出すのは不可で、クラス内部からでもインスタンスメソッドとしては使えない。
private に設定されたメソッドは関数形式でしか呼び出せません
以下、ruby本家(の近くか?)で見つけたFAQ
privateの意味は、メソッドを関数形式でだけ呼び出せるようにし、 レシーバー形式では呼び出せないようにするという意味です。したがって、 可視性がprivateなメソッドは、自クラス及びサブクラスからしか参照 できません。
protectedも同様に、自クラス及びサブクラスからしか参照できませんが、 関数形式でもレシーバー形式でも呼び出せます。
メソッドのカプセル化に必要な機能です。
- protected
メソッドは、クラスの内部(定義クラスとサブクラス)からのみアクセス可
レシーバを指定して呼び出すことができ、クラス内部からであればインスタンスメソッドとして使える。
protected に設定されたメソッドは、そのメソッドを持つオブジェクトが selfであるコンテキスト(メソッド定義式やinstance_eval)でのみ呼び出せ ます。
うう、でもまだよく咀嚼できていないような気満々なので、(きっと)つづく