[ruby-list:192] TUTORIAL - more about method

From: matz@... (Yukihiro Matsumoto)
Date: 1996-02-23 02:16:02 UTC
List: ruby-list #192
まつもと ゆきひろ@トヨタケーラムです.

メソッドのアクセス制御についてです.ちょっと難しいかな.
--
さらにメソッドについて(アクセス制御)

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: method `sqr' not available for main(Object)

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

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

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

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

`undefined'ではなく,`not available'であるというわけだ.逆に
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
 Test
 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
 Test2
 ruby> test2 = Test2.new
 #<Test2:0xbb440>
 ruby> test.foo
 ERR: method `foo' not available for #<Test2:0xbb440>(Test2)
 ruby> test2.bar
 bar -> foo
 nil

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

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

In This Thread

Prev Next