クラスはオブジェクトの母であってクラスの子であるオブジェクトです

こういう表現は「クレタ人は嘘つきである」と言った、クレタ人のセリフに聞こえるでしょう。1 でもわたしはクレタ人ではありません。Rubyワールドにおいてこの表題は事実なのです。

先に「オブジェクトは内部に多数のメソッドを持っており」と書きましたが、実際には持っていません。Rubyはクラスベースのオブジェクト指向言語であり、実際にメソッドを持っているのはオブジェクトの雛型となっているクラスです。オブジェクトはメッセージを受けると、密かに自分の属するクラスにアクセスして結果を得ているのです。

例えば ‘donkey’.length というコードでは、文字列オブジェクト’donkey’は自分ではlengthメソッドを持っておらず、その属するStringクラスに問い合わせをして結果を得ます。基本的にすべてのメソッドはクラスが持っており、オブジェクトは自分の属性情報(自身のIDとか属するクラス名とか)しか持っていません。

つまりオブジェクトは「知らないことは俺に聞け!」と言って、陰でググってるわたしと大差ないのです!

Rubyには40以上の標準添付のクラスがあり、それぞれがその特性を示すような多数のメソッドを備えています。自分で新しいクラスを作ることも、他の人が作ったクラスを取り込むこともできます。2オブジェクトはほぼ例外なく、これらの何れかのクラスから生成されます。3

クラスとメソッドを一望できるページを作りましたので、どんなクラスがあってどんなメソッドを持っているかここで確かめてください。

Ruby 1.9.2 Methods List

各メソッドはRubyリファレンスマニュアルにおけるメソッド解説にリンクしていますから、リンクを辿れば詳細を知ることができます。

一般にクラスはオブジェクトの雛型であると言われます。わたしもさっきそう言いました。でも雛型というと設計図をイメージします。そしてその設計図に基づいて、建造物という実体が作られるとイメージします。

しかしそのイメージはRubyのクラスに関しては正しくありません。なぜならRubyにおいてクラスは実体だからです。つまりクラスもメモリ空間の一部を占有するオブジェクトなのです。ですからクラス自身もメッセージを受信します。

Hash.ancestors # => [Hash, Enumerable, Object, Kernel, BasicObject]

クラスはメッセージを受けると自身の中に対応するメソッドを探し、あればそれを起動し結果を返します。このクラスに直接送られるメソッドを特にクラスメソッドと呼ぶことがあります。

前でオブジェクトはメッセージを受けると、属するクラスにメソッドを問い合わせると書きました。ではそのクラスが、対応するメソッドを持っていないときはどうなるでしょう。その答えが上のancestorsです。

ここで出力されたクラス群はHashクラスと血の繋がりはありませんが、武芸の師匠といった位置づけのクラスです。4 だからancestorsというよりteachersといったほうがぴったりきます。つまりクラスが対応するメソッドを持たない場合、そのancestorsに順次問い合わせて答えを得ます。このような仕組みを技芸の継承・文化の継承に倣って、クラスの継承といいます。

すべてのクラスが答えることができるクラスメソッドはnewです。これはその属するオブジェクトを生み出すものです。

charlie = Person.new('Charlie', 12, :male)

Personクラスに名前、年齢、性別の属性情報を渡して、newメソッドを呼んでいます。

これでメモリ空間に1つの人オブジェクトが生まれます。このときnewメソッドを受けるクラスが既にオブジェクトとして、メモリ空間に生成されているということを忘れないでください。

誰がオブジェクトの母親かはclassメソッドで知ることができます。

carlie.class # => Person
 'alligator'.class # => String
 [1, 2, 3].class # => Array

ではオブジェクトを生み出すクラスは誰が生み出すのでしょう。答えは上と同様クラスにclassメソッドを送れば得られます。

String.class # => Class
 Array.class # => Class
 Person.class # => Class

RubyにおけるアダムとイブはClassという名を持ったクラスでした。次なる疑問は「ではClassクラスはいったい誰が生むのか?」です。これはご自身で試してみてください。驚愕の事実が得られます。

以上でクラスについてのこの項の説明は終わりです。わたしはクレタ人にならずに済んだでしょうか。

クラスに関して更に知りたい方は以下を参考にしてみてください。

Rubyのクラスはオブジェクトの母、モジュールはベビーシッター

(次回に続く)

  1. [自己言及のパラドックス - Wikipedia](http://ja.wikipedia.org/wiki/%E8%87%AA%E5%B7%B1%E8%A8%80%E5%8F%8A%E3%81%AE%E3%83%91%E3%83%A9%E3%83%89%E3%83%83%E3%82%AF%E3%82%B9
  2. kernelモジュールのrequireメソッドを使います
  3. ARGFのようなクラスを持たないオブジェクトもあります
  4. 正確にはEnumerableと Kernelはモジュールという特殊なクラスです


blog comments powered by Disqus
ruby_pack8

100円〜で好評発売中!
M'ELBORNE BOOKS