ruby デバッグに便利な関数
Ruby の内部データ構造は union やハッシュテーブルを駆使してあって、デバッガで直接データを読むのはかなりつらい。幸い、構造体からデータを取り出すための関数が充実している(と思われる)ので、それらを使えば効率的に内部構造を調べることができる。
例えば、関数を使わずにクラスを指す VALUE klass からスーパークラスの VALUE を取り出すためには以下のようにする必要がある。
(gdb) p ((struct RClass*)klass)->super $198 = 3086056660
ruby の C API である rb_class_superclass() を使えば、同じことが以下のように書ける。
(gdb) p rb_class_superclass(klass) $195 = 3086056660
これはまだ簡単な方で、klass の属するクラス名を知りたいと思うと以下のようなステップを踏む必要がある。
1. klass を struct RClass* にキャスト
2. 文字列 "__classid__" を Symbol に変換
3. struct RClass のメンバ iv_tbl はハッシュテーブル。これから 2. で求めた Symbol をキーにした値をとりだす。
4. 取り出した値を文字列に変換。
以上をデバッガで正直に追っていくのは実用上不可能に近い。
しかし、C API の rb_class2name を使えば、以下のように簡単にクラスの名前を調べることができる。
(gdb) p rb_class2name(klass) $199 = 0xb7ed8a00 "C"
デバッグに使えるこういう関数が他にもたくさんあるはずだが、その一覧のようなものはまだ見つけてない。