rubyのクラスメソッドについて
理解があやふやだったのですが、
この記事を読んでスッキリと霧が晴れました。
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/31193
1. Rubyのメソッドは、次の2種類に分けられます。
- インスタンスメソッド
- 特異メソッド
1.1. インスタンスメソッドは、そのクラスのインスタンスはどれでも使えま
す。これに関しては特に理解に問題はないかと思います。
例: class A def a print "a" end end a1 = A.new a2 = A.new a1.a # => "a" a2.a # => "a"
1.2. 特異メソッドは、ある特定のオブジェクトだけが使えるメソッドです。
これを定義するには、通常、"def クラス名.メソッド名" という書式を
使います(*1)。
例: a3 = A.new def a3.aa print "aa" end a3.aa # => "aa" a1.aa # => エラー
この特異メソッドの概念は、C++やJavaにはないものです。
2. Rubyでは、クラスも一つのオブジェクトです。
クラスを定義するということは、クラスオブジェクトを一つ生成するとい
うことでもあります。クラスAを定義すると、Aというクラスオブジェクト
が作られるわけです。
クラスメソッドは、このクラスオブジェクトが持つ特異メソッドです(*2)。
例: (1.2の例と見比べてみてください) def A.aaa print "aaa" end A.aaa # => "aaa"
クラスメソッドを使えるのはクラスオブジェクトAという特定のオブジェク
トだけですから、そのクラスのインスタンスa1、a2、a3では使えません。
例:
a1.aaa # => エラー
2.1. 但し、クラスオブジェクトは、特異メソッドに関して通常のオブジェク
トとは少し異なった特殊な振る舞いをします。
2.1.1. クラスオブジェクトは、上位クラスの特異メソッドを受け継ぎます。
これは「ある特定のインスタンスだけが使える」という特異メソッド
の性質に対する例外です(*3)。
例: class B < A end B.aaa # => "aaa"
2.1.2. (ほかにありましたっけ?)
2.2. いってみれば、Rubyでは、クラスオブジェクトの特異メソッドを、
2.1節のような特殊な取り扱いをすることで、C++やJavaのクラスメソッド
を「模倣」しているのだ、といえます。
ですから、Rubyの世界をストレートに理解するためには、クラスメソッド
という概念をことさらに意識する必要はないと思います。