Ruby Users' Guide - さらにメソッドについて(アクセス制御)

前 - コピー - 次 - 目次

### さらにメソッドについて(アクセス制御)

rubyには関数がなく，全てメソッドであると説明した．ただし，メ ソッドには種類があって，実際はもうちょっと複雑である．このメ ソッドの種類は「アクセス制御」とも呼ばれて，メソッドの呼び出 し方の制限になっている．

まず，トップレベルで関数(メソッド)を定義してみよう．

     ruby> def sqr(n)
     ruby|   n * n
     ruby| end
     nil
     ruby> sqr(5)
     25

クラスの外側のdefはObjectクラスにメソッドを追加することにな る．全てのクラスはObjectクラスを継承しているから，全てのクラ スでsqrが呼び出せるようになったわけだ．

では，全てのクラスからsqrが呼べるはずなので，sqrをselfに対し て呼び出してみよう．

     ruby> self.sqr(5)
     ERR: private method `sqr' called for main(Object)

エラーになった．話が違う．

実はトップレベル(classの外側)で定義されたメソッドは，関数形 式でしか呼び出せないようになっているのだ．これは「関数のよう に見えるものは関数のように振舞わせよう」というポリシーからだ．

だから，未定義のメソッドを呼び出した時とはエラーメッセージが 違っている．

     ruby> undefined_method(13)
     ERR: undefined method `undefined_method' for main(Object)

`undefined'ではなく，`private'であるというわけだ．逆に classの中で定義されたメソッドはデフォルトのままでは自由に呼 び出せる．

     ruby> class Test
     ruby|   def foo
     ruby|     print "foo\n"
     ruby|   end
     ruby|   def bar
     ruby|     print "bar -> "
     ruby|     foo
     ruby|   end
     ruby| end
     nil
     ruby> test = Test.new
     #<Test:0xbae88>
     ruby> test.foo
     foo
     nil
     ruby> test.bar
     bar -> foo
     nil

`bar'というメソッドの中では`foo'を関数形式で呼び出している．

もし，あるメソッドが関数形式でしか呼び出されないとしたら，そ のメソッドを定義したクラスか，そのサブクラスのメソッドからし か呼ばれないので，C++のprotectedのような働きをするだろう．つ まり，外側から勝手に呼ばれないメソッドになるわけだ．

メソッドの性質を変えるにはprivate, publicというメソッドを使 う．使い方を見てみよう．

     ruby> class Test2
     ruby|   def foo
     ruby|     print "foo\n"
     ruby|   end
     ruby|   private :foo
     ruby|   def bar
     ruby|     print "bar -> "
     ruby|     foo
     ruby|   end
     ruby| end
     nil
     ruby> test2 = Test2.new
     #<Test2:0xbb440>
     ruby> test2.foo
     ERR: private method `foo' called for #<Test2:0x8a658>(Test2)
     ruby> test2.bar
     bar -> foo
     nil

`private :foo'という行を加えたので，メソッドfooを`test.foo' という形では呼び出せなくなったのが分かるだろう．逆に一度 privateになったメソッドをどの形式でも呼び出せるようにするた めには，`public :メソッド名'とする．メソッド名を指定する時には， メソッド名の前の`:'を忘れてはいけない．忘れるとメソッド 名ではなく，ローカル変数の参照と見なされて，いろいろとややこ しいエラーになる．

privateなメソッドはいわゆる関数と同じような働きをする．ただ し，やはりメソッドなので，クラスが違えば同じ名前を使ってもよ いところが違うところだ．

前 - コピー - 次 - 目次