RHG 片手に Ruby 1.9 を読む集い(The RHG Strikes Back)に参加した(3) - 第3回 RHG の逆襲
クラスとメタクラス
詳細は RHG を参照して欲しいのですが、Ruby の世界ではクラスもまたオブジェクトとして扱われます。Ruby ではそのクラスのオブジェクトに特異メソッドを定義することで、クラスにスタティックなメソッド(クラスメソッド)を定義しています。
言い換えると、クラスにスタティックなメソッド(クラスメソッド)を定義するとそのクラスの特異クラスのメソッドとして定義されるということになります。クラスのクラスであるため、クラスの特異クラスをメタクラスと呼びます。
以下の図を見ると、Class クラスはメタクラスの親クラスになっていることがわかります。Ruby ユーザーからはクラスは Class クラスのインスタンスですが、C レベルでは特異クラスがメタクラスとして間に挟まっていることがわかります。
クラスとメタクラス(by Kodougu)
クラスの継承構造に従ってメタクラスも継承することに注意してください。これは、「メタクラスを継承させることで、子クラスでも親クラスで定義したクラスメソッドを呼び出せるようにするため」と考えられます。
(2008/4/9 星さんにいただいたコメントにより追記。)
特異クラスは特異メソッドを定義した際に定義されます。しかし、メタクラスはクラスが定義されたときに特異メソッドの有無に関わらず生成されます。同じ特異クラスでありながら扱いが異なる理由は、勉強会では、「クラスの場合、特定のクラスの特異クラスを作ると親クラスの特異クラスも同時に生成しなければならないため、あらかじめ作成しておくのではないか」という指摘がありました。
クラスの継承とモジュールのインクルード
Ruby には、mixin を実現するためのモジュールという機構があります。モジュールは一見すると多重継承のような機構に見えますが、Ruby の世界では単一継承モデルで実装されています。
モジュールのインクルード(by Kodougu)
図の通り、モジュールをインクルードすると、Ruby ユーザーから見えないクラス(RHGでは化身クラス)を生成して継承の間に挟み込むということをしています。
その他
勉強会では、Ruby の挙動が怪しい(バグ、もしくは仕様がない?)ところを見つけてしまうこともたまにあります。今回の勉強会で見つかった怪しいところは、星さんがレポートしているので、あわせて参照してください。
まとめ
以上、第3回RHGの逆襲でした。特異クラス、メタクラス、モジュールのインクルードなどを実現するために、Ruby からは見えないクラスを C レベルで作成していることがわかりました。この概念を押さえておけば、難解なクラス・メソッドの定義も多少読みやすくなることでしょう。
さて、次回勉強会では、Ruby のガベージコレクションの仕組みを学習する予定です。RHG的には、第5章 ガ-ベージコレクションに相当します。もし次回から参加される方がいれば、少なくとも RHG で紹介されているガベージコレクションの仕組みは予習しておく必要があるでしょう。
主催者の皆様、有意義な勉強会をありがとうございました。次回も参加することができたら、本ブログで紹介したいと思います。それでは!
1 2
このサイトについて
TrackBack URL :

先日はお疲れ様でした。個人的にもいろいろアドバイスを賜り、ありがとうございました。
なぜ「クラスの特異クラス同士が継承しあうのか」も説明したほうがよいかと存じます。僕の考える理由は、「そうすると便利だから」というものです。たとえば:
class A; def self.foo; end; end
class B < A; end
で B.foo を呼べるようにするためではないかと思っています。
クラスの特異クラスが継承関係であるようになっているのは必然ではなく、 rb_make_metaclass 関数をつかってそうなるように仕向けているからなので、そのようにした理由が何かしらあるはずです。
Posted by 星一 | 2008年04月08日 21:25
コメントありがとうございます!
また、勉強会ではお疲れさまでした。
RHG にも「クラスの特異クラス自身がクラスと連動して継承するため、
クラスメソッドが継承される」と書かれていますから、おっしゃる
とおりクラスメソッドの継承を意図しての実装と考えられます。
確かにそこを説明しないと、読み手にかなりの想像力を要求することに
なりそうですので、後ほど対応しておきます。
だんだんと勉強会の内容が濃くなっていっているため、記事に起こせる
内容がごく限られた範囲になってきました。どこかで勉強会の成果を
ある程度網羅して形に残す機会を作りたいですね。
Posted by あかさた | 2008年04月08日 23:19