Rubyチュートリアル 〜英文小説の最頻出ワードを見つけよう!(その4)
クラスはオブジェクトの母であってクラスの子であるオブジェクトです
こういう表現は「クレタ人は嘘つきである」と言った
クレタ人のセリフに聞こえるでしょう*1
でもわたしはクレタ人ではありません
Rubyワールドにおいてこの表題は事実なのです
先に「オブジェクトは内部に多数のメソッドを持っており」と
書きましたが実際には持っていません
Rubyはクラスベースのオブジェクト指向言語であり
実際にメソッドを持っているのは
オブジェクトの雛型となっているクラスです
オブジェクトはメッセージを受けると
密かに自分の属するクラスにアクセスして結果を得ているのです
例えば 'donkey'.length というコードでは
文字列オブジェクト'donkey'は
自分ではlengthメソッドを持っておらず
その属するStringクラスに問い合わせをして結果を得ます
基本的にすべてのメソッドはクラスが持っており
オブジェクトは自分の属性情報
(自身のIDとか属するクラス名とか)しか持っていません
つまりオブジェクトは「知らないことは俺に聞け!」と言って
陰でググってるわたしと大差ないのです!
Rubyには40以上の標準添付のクラスがあり
それぞれがその特性を示すような多数のメソッドを備えています
自分で新しいクラスを作ることも
他の人が作ったクラスを取り込むこともできます*2
オブジェクトはほぼ例外なく
これらの何れかのクラスから生成されます*3
クラスとメソッドを一望できるページを作りましたので
どんなクラスがあってどんなメソッドを持っているか
ここで確かめてください
各メソッドは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
(次回に続く)