Ruby本体読みはじめた人に届けたいドキュメント
RubyKaigi2017に参加してやる気が高まったので最近は ruby/ruby のコードを読むようになってます。
しかしこれがなかなか読むのにコツがいる感じです。
RubyKaigi参加前は “Ruby under a microscope”1 を読んで「Rubyの内側面白い!!!」ってなってたのですが、実際にCのソース読みはじめると全然違いますね。マクロ多いし、C言語のこともわからんし……。
Ruby Hacking Guide こと 『Rubyソースコード完全解説』2 を読んだほうがいいのかもと悩むようになりました。
でもそんな悩みも今日解決されました。これ読めばとりあえずはRubyのレポジトリを泳げるようになりそうです。
ruby/extension.ja.rdoc at trunk · ruby/ruby · GitHub
これが非常によいです。まず読んでて面白いし噛み砕かれている感じがある。飽きずに読める感じです。
RubyKaigiに参加して Ruby 本体読むぞーって人はまずここからやってみてはいかがでしょうか。
いまだいたい25%くらい読んだのでメモった内容(というかslackログ)を以下に記しておきます。
まだまだわからんことだらけですのでこれ読んどけとか、このへんから入るのが手頃とか教えてもらえるとうれしいです〜
せっかくだからメモっておくか
INT2FIX() :: もとの整数が31bitまたは63bit以内に収まる自信 がある時
「自信がある時」
rb_str_resize(VALUE str, long len) :: Rubyの文字列のサイズをlenバイトに変更する.strの長さは前 以てセットされていなければならない.lenが元の長さよりも短 い時は,lenバイトを越えた部分の内容は捨てられる.lenが元 の長さよりも長い時は,元の長さを越えた部分の内容は保存さ れないでゴミになるだろう.この関数の呼び出しによって
“”“ゴミになるだろう”“”
さっきから思ってたんだが rb_ary_new2 とか rb_ary_new3とかあるのな
~/.g/g/h/ruby ❯❯❯ git grep rb_ary_new2 | wc -l 123 ~/.g/g/h/ruby ❯❯❯ git grep rb_ary_new3 | wc -l 110
4まであって草
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
なんかしてるのかなーって思ったら定義済みの定数があるか探して、あればクラスであること、スーパークラスが同じであることを確認、なければ普通にクラスつくってからouterにassign
まあ想定どおりの動きであった
これ rb_define_class も rb_cObject に対して同じことやってね?
ああ、でも細かいところの処理違うのだな。
これらの関数の argcという引数はCの関数へ渡される引数の数(と 形式)を決めます.argcが0以上の時は関数に引き渡す引数の数を意 味します.16個以上の引数は使えません(が,要りませんよね,そ んなに).実際の関数には先頭の引数としてselfが与えられますの で,指定した数より1多い引数を持つことになります.
cfuncは必須引数15個までなのか
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_visibility_t visi) { if (argc < -2 || 15 < argc) rb_raise(rb_eArgError, "arity out of range: %d for -2..15", argc);
argcが負の時は引数の数ではなく,形式を指定したことになります. argcが-1の時は引数を配列に入れて渡されます.argcが-2の時は引 数はRubyの配列として渡されます.
-2のとき……
~/.g/g/h/ruby ❯❯❯ git grep 'rb_define_method.*-2' enumerator.c: rb_define_method(rb_cYielder, "yield", yielder_yield, -2); enumerator.c: rb_define_method(rb_cYielder, "<<", yielder_yield_push, -2); ext/win32ole/win32ole_typelib.c: rb_define_method(cWIN32OLE_TYPELIB, "initialize", foletypelib_initialize, -2); ext/win32ole/win32ole_variant.c: rb_define_method(cWIN32OLE_VARIANT, "initialize", folevariant_initialize, -2); io.c: rb_define_method(rb_cARGF, "initialize", argf_initialize, -2); thread.c: rb_define_method(rb_cThread, "initialize", thread_initialize, -2);
-2なんで使うのかよくわからんかった
Cの世界を通らずにそのままRuby to Rubyで動かせるからかな
-
https://www.amazon.co.jp/dp/B01IGW56CU/ 『Rubyのしくみ』なんだけど『言語のしくみ』と紛らわしいのでよくマイクロスコープ、アンダーアマイクロスコープと呼ばれている気がする。↩
-
https://www.amazon.co.jp/dp/4844317210 中古が高いことで有名↩