Rubyチュートリアル 〜英文小説の最頻出ワードを見つけよう!(その4)

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

こういう表現は「クレタ人は嘘つきである」と言った
クレタ人のセリフに聞こえるでしょう*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のクラスはオブジェクトの母、モジュールはベビーシッター - hp12c


(次回に続く)

*1:自己言及のパラドックス - Wikipedia

*2:kernelモジュールのrequireメソッドを使います

*3:ARGFのようなクラスを持たないオブジェクトもあります

*4:正確にはEnumerableと Kernelはモジュールという特殊なクラスです