[ruby-list:50613] Re: [質問] メタプログラミングRuby(第1版)の include時の無名クラス という記載について

From: Shugo Maeda <shugo@...>
Date: 2017-12-04 15:28:57 UTC
List: ruby-list #50613
前田です。

2017年12月3日 22:21 モコあき <mokoriso@gmail.com>:
> Rubyの内部事情(?)をメタプログラミングRuby(第1版)がそのように表現しただけで、実際にアクセス出来るような代物ではない
> => その無名クラスへのアクセスは諦めてください

実装の都合で用意されている内部的なオブジェクトなので普通の方法ではアクセスできません。

例えば、デバッガを使うと確認することができます。
# Rubyのソースを展開してビルドしたディレクトリでの実行を想定しています。

$ gdb --args ruby -e 'Array.send(:!)'
(gdb) # !メソッドにブレークポイントを設定
(gdb) b rb_obj_not
Breakpoint 1 at 0x95c20: file object.c, line 222.
(gdb) # プログラムを実行
(gdb) run
Starting program: /home/shugo/src/ruby/ruby -e Array.send\(:\!\)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7ff5700 (LWP 4892)]

Thread 1 "ruby" hit Breakpoint 1, rb_obj_not (obj=93824998061360)
    at object.c:222
222         return RTEST(obj) ? Qfalse : Qtrue;
(gdb) # rb_pはRubyのp相当。
(gdb) rb_p obj
Array
(gdb) # rpはオブジェクトのCレベルの構造を表示。T_CLASSは普通のクラスのこと。
(gdb) rp obj
[PROMOTED] T_CLASS: (struct RClass *) 0x555555ae3530There is no member
named origin.
(gdb) # RCLASS(obj)->superがEnumerableをラップする無名のクラス。T_ICLASSは無名クラスのこと。
(gdb) rp RCLASS(obj)->super
T_ICLASS: (struct RClass *) 0x555555ae34e0There is no member named origin.
(gdb) # RBASIC(iclass)->klassでiclassがラップしているモジュールを参照。
(gdb) rb_p RBASIC(RCLASS(obj)->super)->klass
Enumerable

あと、無名クラスという呼び方はClass.newで名前を付けずに作ったクラスと紛らわしいかも
しれません。
CコードではT_ICLASSという名前が使われているので、ICLASS(大文字小文字は人による)
とか呼ばれることが多いですかねえ。

-- 
Shugo Maeda

In This Thread