Ruby Inside

Module#class_eval でメソッド定義するときのローカルスコープ

前回のまとめ(*) でこう書いた。 exec_under() は、クラス A を現在の cref スタックに追加した新たな cref スタックを、lfp[-1] すなわちローカル変数領域の内部用特別領域に保管する。このローカル変数のスコープが何かについては、今回は調べていない。 …

クラスメソッドからクラス変数を参照 - class_eval で定義されたクラスメソッドの場合 (ruby 1.9) [その2]

Module#class_eval で定義されたクラスメソッドの命令列の cref スタックは、通常の場合と違いlfp_get_special_cref() で返される cref スタックとなる。 lfp_get_special_cref() は他のクラスメソッド定義のやり方のときは値を返さなかったので、Module#cla…

クラスメソッドからクラス変数を参照 - class_eval で定義されたクラスメソッドの場合 (ruby 1.9) [その1]

前回「最後のパターン」などと書いたが、ドラえもんや巨人の星で分かる通り、「最後」というのは当てにならない。ということで、今回もクラスメソッドとクラス変数の話が続く。 今回は Module#class_eval の中で定義したクラスメソッドの中からクラス変数を…

クラスメソッドからクラス変数を参照 - 特異クラス内で定義されたクラスメソッドの場合 (ruby 1.9)

クラスメソッドからクラス変数を参照。最後のパターンは、特異クラス内で定義されたクラスメソッドの場合だ。調べる Ruby のプログラムは以下の通り。 class A @@a = "Hello" end class <<A def test_sclass puts @@a end end A.test_sclass (test_sclass.rb) 特異クラス定義の部分は、どういう VM 命令列になるのだろうか?アセンブリコードを見てみよう。 == disasm: @test_sclass.rb>================================= 0000 putnil 0001 …</a>

トップレベルのクラスが Object でないこともある

昨日コードを調べたとき、一つ気になったことがある。 prepare_iseq_build(rb_iseq_t *iseq, VALUE name, VALUE filename, VALUE parent, VALUE type, VALUE block_opt, const rb_compile_option_t *option) { rb_thread_t *th = GET_THREAD(); ............…

クラスメソッドからクラス変数を参照 - クラス外で定義されたクラスメソッドの場合 (ruby 1.9) [その2]

問題となっている cref は iseq->cref_stack から来ている。どういう経緯でここに Object クラスが設定されたのかを知りたい。 手始めに iseq->cref_stack を初期化しているところを探してみる。cref_stack という文字列でファイル検索をかけると 20 箇所ほ…

クラスメソッドからクラス変数を参照 - クラス外で定義されたクラスメソッドの場合 (ruby 1.9) [その1]

今回は、クラス外で定義されたクラスメソッドからクラス変数を参照する場合の内部動作を調べてみる。Ruby のコードは以下のとおり。 class A @@a = "Hello" end def A.test_out puts @@a end A.test_out 前回やったのと同じ要領で、puts @@a に対応する YARV…

read only クラス変数

最新版の ruby 1.9 (r11928) で下のコードを走らせてみると、以下のような結果になる。 class A @@v = "I'm A" def A.av @@v end end class B < A def B.bv @@v end def B.update_v @@v = "I'm B" end end puts B.bv # --> I'm A # B から A の @@v が見える…

クラスメソッドからクラス変数を参照 - クラス内で定義されたクラスメソッドの場合 (ruby 1.9)

今日は、クラス内で定義されたクラスメソッドからクラス変数を参照する場合の、ruby 1.9 内部の動作を調べてみる。調べる Ruby のプログラムは以下の通り。 class A @@a = "Hello" def A.test_in puts @@a end end A.test_in # --> Hello (test_in.rb) puts …

クラスメソッドとクラス変数

昨日まで調べていた ruby 1.9 の新機能、クラスローカルインスタンス変数が、最新のリビジョン(11813)では取り除かれている。 どうやら、この辺りの事情のようだ。 ごもっともなご意見である。 というわけで、今日はターゲットを変更して、クラス変数を調べ…

eval_get_cvar_base() と CREF

前回のおさらい。 クラスローカルインスタンス変数を、クラスからしか見えなくするために、クラスとインスタンス変数名の組でしかアクセスできない仕組みが 1.9 で導入された (ivar2)。変数名はそのものずばり "@_a" のような名前だが、クラスは eval_get_cv…

クラスローカルインスタンス変数

1.9 で最近導入されたクラスローカルインスタンス変数について少し調べてみた。クラスローカルインスタンス変数とは、C++ のプライベート変数のようなもので、サブクラスから参照することができない。現在の 1.9 の実装では @_ で始まるクラス変数がクラスロ…

ruby デバッグに便利な関数

Ruby の内部データ構造は union やハッシュテーブルを駆使してあって、デバッガで直接データを読むのはかなりつらい。幸い、構造体からデータを取り出すための関数が充実している(と思われる)ので、それらを使えば効率的に内部構造を調べることができる。…

注釈 RHG - Ch15 メソッド

今日は gdb を使って構文木あたりの動作を調べていたら、足がすべって YARV の方まで突入してしまった。2日目にして早くも RHG から離れている。今日は注釈でもなんでもない、疑問。第15章 メソッド http://i.loveruby.net/ja/rhg/book/method.html obj.met…