トップ » 技術記事 » RHG 片手に Ruby 1.9 を読む集い(The RHG Strikes Back)に参加した(3) - 第5回 RHG の逆襲

RHG 片手に Ruby 1.9 を読む集い(The RHG Strikes Back)に参加した(3) - 第5回 RHG の逆襲

タグ: Ruby

どうも、あかさたです。6/8(日)に第5回 RHG の逆襲(Ruby 1.9 のソースコードを読む勉強会)が行われました。前回に引き続き今回も参加したので、その勉強会の内容をレポートします。

概要

勉強会の趣旨などは以前の記事を読んでいただくとして、当日の概要を紹介します。

第5回も前回までと同じく新橋(汐留)のミラクル・リナックス株式会社さんの会議室で行われました。参加人数は約8名、スクール形式に座って発表者が発表しつつ、適宜参加者が自由にツッコミを入れていくというスタイルです。

以下、発表者のリストです。

  • 澤田さん(スライドによる発表)
  • Yugui さん(適宜補足)

第5回 RHGの逆襲

今回の内容は RHG でいうところの「第6章 変数と定数」と「第7章 セキュリティ」に対応する部分の勉強会を行いました。

「無印」「_0」「_from」「_at」の謎?

Ruby のソースコードでは、関数名で「rb_const_get」「rb_const_get_0」「rb_const_get_at」「rb_const_get_from」(variable.c)などのように、名前からだけでは動作の違いがわからない関数が存在します。

今挙げた関数は、型名と定数のIDを与えると定数を返してくれる関数です。興味のある人はソースコードを確認して欲しいのですが、「rb_const_get」「rb_const_get_at」「rb_const_get_from」は「rb_const_get_0」のラッパーメソッドです。「rb_const_get_0」は bool(int ですが)で「exclude」「recurse」という引数をもっており、ラッパーメソッドはこの引数の値を変えて「rb_const_get_0」を呼び出しているに過ぎません。

「recurse」は親クラスを探索するかどうか設定します。「exclude」はfalseだと型が Module の場合に Object の定数も探索するようです(Module は Object のサブクラス。ちなみに、コード上で定義したモジュール、つまり Module クラスのインスタンスは Object のサブクラスにならないことに注意してください。)。「rb_const_get_at」「rb_const_get_from」の違いは、親クラスを探索するかどうかなのですが、名前だけではなかなか理解することができません。

Ruby のソースコードではよく見られるパターンですが、関数名からどのような違いがあるのかわかりにくいので、読んでて立ち止まってしまうことがあります。「設計では名前重要!」といいつつも、全てのコードの名前を吟味することも難しいのかもしれません。コミッタの Yugui さんが名前のわかりにくさについて気にされていたので、そのうちラッパーメソッドを無くすか、名前がわかりやすくするか、何らかのリファクタリングがなされる可能性はあります。ただ、Ruby 全体でこのような書き方がなされているため、難しいかもしれませんが。

定数の探索順

定数の探索順は前述の「rb_const_get_0」関数を読めば理解することができます。勉強会では以下のようなコードを動かしながら、探索順を確認しました。

class C
  CONST = "Class C CONST"
end

CONST = "Global(Object) CONST"

module M
  CONST = "Module M CONST"

  module MM
    CONST = "Module MM CONST"
  end

  class D < C
    include MM
    CONST = "Class D CONST"

    def self.output_const
      p CONST
    end
  end
end

定数探索の Ruby コード例(定数の定義をそれぞれコメントアウトして試してください。)

上記のコードで「M::D.output_const」メソッドを呼び出すと、定数は「”Class D CONST”」「”Module M CONST”」「”Module MM CONST”」「”Class C CONST”」「”Global CONST”」の優先順位で探索されます。具体的には、この場合は「”Class D CONST”」が出力されます。

グローバル変数の種類

Ruby ではフックされたグローバル変数(rb_define_hooked_variable 関数で定義)と仮想のグローバル変数(rb_define_virtual_variable 関数で定義)というものがあるようです。Ruby のグローバル変数と言えば、「$SAFE」などのように「$」が先頭についています。

グローバル変数の読み書き時に setter/getter を設定したものがフックされたグローバル変数です。フックされたグローバル変数の特殊なケースとして、値を持たない仮想のグローバル変数が存在するようです。前述の「$SAFE」は仮想のグローバル変数です。この変数はセキュリティレベルなので、C レベルではもちろん値をもっていますが、Ruby レベルでは管理されていません。

セキュリティ

処理系もしくは付属するフレームワークにある程度のセキュリティ機構が付属することはよくあることです。Ruby には、外部から入ってきたデータに対してマーク(汚染フラグを立てる)をする機構と、セキュリティのレベル(0,1,2,3,4)に応じて操作の実行を制限する機構があります。RHG の内容は今でもだいたい通用するので、詳しくは RHG を参照してください。

Ruby のセキュリティモデルは、CGI などで力を発揮するように考えられたセキュリティモデルのようです。個人的にはサンドボックスのようなものを構築するには少し不足しているので、そういう方向性でも機能拡張されるとうれしいのですが。

まとめ

今回はあまりネタがなかったせいか、勉強会はさらっと終わってしまいました。その分、懇親会で技術談義が盛り上がったように思います。次回は RHG で言うところの「第10章 パーサ」です。そろそろ RHG の内容から大きくずれていくことになるでしょう。「第8章 Ruby言語の詳細」と「第9章 速習yacc」は、ソースコード内部ではなく一般知識であるため、必要であるなら各自自習ということになりました。

主催者の皆様、有意義な勉強会をありがとうございました。次回も参加することができたら、本ブログで紹介したいと思います。それでは!

Series Navigation«第3回 RHG の逆襲第4回 RHG の逆襲»

執筆者紹介

あかさた

あかさた

未踏(2006年度下期)でWeb上で動作するモデリング環境 Kodougu の開発をしてました。こちらでもブログを書いています。

TrackBack URL :