Submit Search
Rubyのコードを読んでみよう(オブジェクト編)
1 like
959 views
baban ba-n
1 of 35
Download now
Download to read offline
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
More Related Content
PDF
TypeScript & 関数型講座 第2回 TypeScript という言語
gypsygypsy
PDF
JVMの中身を可視化してみた
Kengo Toda
PDF
Java開発の強力な相棒として今すぐ使えるGroovy
Yasuharu Nakano
PDF
Hacking Ruby with Python
Taisuke Yamada
PPTX
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
Koichi Sakata
PDF
JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」
y torazuka
PPTX
資料
Bob_Mk2
PDF
Rubyの拡張をCrystalで書いてみる
5t111111
TypeScript & 関数型講座 第2回 TypeScript という言語
gypsygypsy
JVMの中身を可視化してみた
Kengo Toda
Java開発の強力な相棒として今すぐ使えるGroovy
Yasuharu Nakano
Hacking Ruby with Python
Taisuke Yamada
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
Koichi Sakata
JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」
y torazuka
資料
Bob_Mk2
Rubyの拡張をCrystalで書いてみる
5t111111
What's hot
(20)
PDF
Unityで覚えるC#
Masamitsu Ishikawa
PPTX
メタプログラミングってなに?
KazukiWata
PDF
js-ctypes - ネイティブコードを呼び出す新しいカタチ
Makoto Kato
PDF
Haml 学習コース 初級編
介翔 鈴木
PDF
Java 7 invokedynamic の概要
Taku Miyakawa
PDF
JavaScript経験者のためのGo言語入門
Shohei Arai
PDF
ラムダと invokedynamic の蜜月
Taku Miyakawa
PPT
第4回勉強会 Groovyの文法からSpockまで
Mugen Fujii
PDF
プログラムの処方箋~健康なコードと病んだコード
Shigenori Sagawa
PDF
Boost.Flyweight
gintenlabo
PDF
JavaScript基礎勉強会
大樹 小倉
PDF
C++でCプリプロセッサを作ったり速くしたりしたお話
Kinuko Yasuda
KEY
JJUG CCC 2012 Real World Groovy/Grails
Uehara Junji
PDF
第2回勉強会スライド
koturn 0;
PDF
覚醒!JavaScript
Haraguchi Go
PDF
Nodejuku01 ohtsu
Nanha Park
PDF
Swift 2.0 大域関数の行方から #swift2symposium
Tomohiro Kumagai
PDF
第三回ありえる社内勉強会 「いわががのLombok」
yoshiaki iwanaga
PDF
第1回勉強会スライド
koturn 0;
PPTX
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
YujiSoftware
Unityで覚えるC#
Masamitsu Ishikawa
メタプログラミングってなに?
KazukiWata
js-ctypes - ネイティブコードを呼び出す新しいカタチ
Makoto Kato
Haml 学習コース 初級編
介翔 鈴木
Java 7 invokedynamic の概要
Taku Miyakawa
JavaScript経験者のためのGo言語入門
Shohei Arai
ラムダと invokedynamic の蜜月
Taku Miyakawa
第4回勉強会 Groovyの文法からSpockまで
Mugen Fujii
プログラムの処方箋~健康なコードと病んだコード
Shigenori Sagawa
Boost.Flyweight
gintenlabo
JavaScript基礎勉強会
大樹 小倉
C++でCプリプロセッサを作ったり速くしたりしたお話
Kinuko Yasuda
JJUG CCC 2012 Real World Groovy/Grails
Uehara Junji
第2回勉強会スライド
koturn 0;
覚醒!JavaScript
Haraguchi Go
Nodejuku01 ohtsu
Nanha Park
Swift 2.0 大域関数の行方から #swift2symposium
Tomohiro Kumagai
第三回ありえる社内勉強会 「いわががのLombok」
yoshiaki iwanaga
第1回勉強会スライド
koturn 0;
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
YujiSoftware
Ad
Similar to Rubyのコードを読んでみよう(オブジェクト編)
(20)
PDF
Ruby2.0 - refinements - 鳥取Ruby会 第11回
Rie HIRONO
PDF
Ruby2.0について
Shinichirou Nakamura
PDF
Rails初心者レッスン lesson4 2edition
Satomi Tsujita
PDF
mruby for embedded systems
masayoshi takahashi
PDF
RubyとActive Support for expert 2
xibbar
PPTX
DrupalでBDDテストを実施してみる①
iPride Co., Ltd.
PDF
「愛されたい!」と思ったときにJavaで書くRubyクラス
Koichiro Ohba
PDF
named_scope more detail
Kyosuke MOROHASHI
PDF
Android アプリ開発における Gradle ビルドシステム
Yu Nobuoka
PDF
Tdd
Takaya Kotohata
PDF
Rubyのオブジェクト図をもう一度
ionis111
PDF
mruby を C# に 組み込んでみる
Ryosuke Akiyama
PDF
Rubyにメソッドを追加して遊ぶ話
Masaya Konishi
PDF
バカでもわかるRails #05
Daisuke Ishii
PDF
20110820 metaprogramming
Masanori Kado
PDF
Rcppを使って動的もしくは共有ライブラリ (dylib, soファイル)を用いた関数(パッ ケージ)を作る
Satoshi Minakuchi
PDF
Railsの開発環境作るぞ
Yoichi Toyota
PDF
名古屋Ruby会議02 LT:Ruby中級への道
Shigeru UCHIYAMA
PDF
Grails 2.0.0.M1の話
Tsuyoshi Yamamoto
PDF
Haskell 6-module
Mahito Ogura
Ruby2.0 - refinements - 鳥取Ruby会 第11回
Rie HIRONO
Ruby2.0について
Shinichirou Nakamura
Rails初心者レッスン lesson4 2edition
Satomi Tsujita
mruby for embedded systems
masayoshi takahashi
RubyとActive Support for expert 2
xibbar
DrupalでBDDテストを実施してみる①
iPride Co., Ltd.
「愛されたい!」と思ったときにJavaで書くRubyクラス
Koichiro Ohba
named_scope more detail
Kyosuke MOROHASHI
Android アプリ開発における Gradle ビルドシステム
Yu Nobuoka
Tdd
Takaya Kotohata
Rubyのオブジェクト図をもう一度
ionis111
mruby を C# に 組み込んでみる
Ryosuke Akiyama
Rubyにメソッドを追加して遊ぶ話
Masaya Konishi
バカでもわかるRails #05
Daisuke Ishii
20110820 metaprogramming
Masanori Kado
Rcppを使って動的もしくは共有ライブラリ (dylib, soファイル)を用いた関数(パッ ケージ)を作る
Satoshi Minakuchi
Railsの開発環境作るぞ
Yoichi Toyota
名古屋Ruby会議02 LT:Ruby中級への道
Shigeru UCHIYAMA
Grails 2.0.0.M1の話
Tsuyoshi Yamamoto
Haskell 6-module
Mahito Ogura
Ad
More from baban ba-n
(12)
ODP
Typusとadministrateを比較してみよう
baban ba-n
ODP
Typusと付き合ってきた話
baban ba-n
ODP
ハッカソン。来た、見た、負けた! Spajam2016仙台予選
baban ba-n
ODP
ガラホ、なるものに対応してきた
baban ba-n
ODP
Minitest調べてみた
baban ba-n
ODP
人工言語ロジバン超入門編
baban ba-n
ODP
普通のエンジニアが【ロジバン】やってみた
baban ba-n
ODP
プログラミング言語Cyanの紹介
baban ba-n
ODP
Rubyのソースコードを読んでみよう(入門編)
baban ba-n
ODP
rails 管理画面作成gem Typus解説
baban ba-n
PDF
名前重要 超重要
baban ba-n
ODP
Rails-Plugin Flexturesの紹介
baban ba-n
Typusとadministrateを比較してみよう
baban ba-n
Typusと付き合ってきた話
baban ba-n
ハッカソン。来た、見た、負けた! Spajam2016仙台予選
baban ba-n
ガラホ、なるものに対応してきた
baban ba-n
Minitest調べてみた
baban ba-n
人工言語ロジバン超入門編
baban ba-n
普通のエンジニアが【ロジバン】やってみた
baban ba-n
プログラミング言語Cyanの紹介
baban ba-n
Rubyのソースコードを読んでみよう(入門編)
baban ba-n
rails 管理画面作成gem Typus解説
baban ba-n
名前重要 超重要
baban ba-n
Rails-Plugin Flexturesの紹介
baban ba-n
Rubyのコードを読んでみよう(オブジェクト編)
1.
Rubyのコードを読んでみよう:その2
2.
さて今日のお題ですが
3.
コレです
4.
Rubyには他の代表的な言語にない黒魔術的な メソッドがありますが その殆どはrubyのクラスの内側に挟み込まれて 存在しています
5.
具体的には ● モンキーパッチング ● eigenclass(self) ●
Kernel#define_method ● Object#extend ● Kernel#include ● Object#method_missoing Etc...
6.
これらの機能はrubyのruby的な rubyたる、オブジェクト指向と 深く結びついています
7.
今回のお題 これらを手繰りながらrubyの ● クラスって何? ● オブジェクトって何? ●
メソッドって何? ” ”という 定義 を辿って行きましょう
8.
細かいこと ● 解析するversionはruby2.0.0-p0でやりますよ! (1.9系と劇的に違ったりはしていないんですけどね)
9.
Stage1: Classをnewしてみる
10.
クラスの作成(class.c) スタートはrb_class_new→rb_class_bootを呼 び出してここで初期化している VALUE rb_class_new(VALUE super) { Check_Type(super, T_CLASS); rb_check_inheritable(super); return
rb_class_boot(super); }
11.
rb_class_bootは継承先、継承元の設定をしてい るだけとっても素直な作り。 VALUE rb_class_boot(VALUE super){ VALUE
klass = class_alloc(T_CLASS, rb_cClass); RCLASS_SUPER(klass) = super; RCLASS_M_TBL(klass) = st_init_numtable(); OBJ_INFECT(klass, super); return (VALUE)klass; }
12.
マクロを展開していくと、RClassなるものが浮 いてくる VALUE rb_class_boot(VALUE super){ VALUE
klass = class_alloc(T_CLASS, rb_cClass); R_CAST((RClass)(klass))->ptr->iv_tbl = super; R_CAST((RClass)(klass))->m_tbl = st_init_numtable(); OBJ_INFECT(klass, super); return (VALUE)klass; }
13.
Rclass!! クラスの正体はここにある (rubyのオブジェクトを理解するにはここを起点にすると良い) struct RClass
{ struct RBasic basic; rb_classext_t *ptr; struct st_table *m_tbl; // メソッド関係一覧 struct st_table *iv_index_tbl; // インスタンス変数一覧 };
14.
そして、メソッドは、実はforループで探索 して呼び出されている int st_lookup(st_table *table,
register st_data_t key, st_data_t *value){ ... st_index_t i; for (i = 0; i < table->num_entries; i++) { if ((st_data_t)table->bins[i*2] == key) { if (value !=0) *value = (st_data_t)table->bins[i*2+1]; return 1; } } ...
15.
まとめ:その1 ● クラスはCの構造体 ● 抑えておくべきデータ型はクラスの本体 RClassこれを作っている
16.
Stage2: methodをdefineしてみる
17.
Kernel#define_methodの解説 ● define_methodの定義はproc.cにあるのでそこ から順番に手繰る ● rb_define_private_method(rb_cModule,
"define_method", rb_mod_define_method, -1); // proc.c ● rb_mod_define_method(int argc, VALUE *argv, VALUE mod) ● rb_method_entry_set(mod, id, method->me, noex); // vm_method.c ● rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, rb_method_definition_t *def, rb_method_flag_t noex) ● st_insert(register st_table *table, register st_data_t key, st_data_t value)
18.
st_insert(register st_table *table,
register st_data_t key, st_data_t value) このメソッドの、st_tableって構造体 …何処かで見たような気が
19.
メソッドの挿入をしているst_insert ● st_insert(register st_table
*table, register st_data_t key, st_data_t value) このメソッドの、st_tableって構造体 …何処かで見たような気が struct RClass { struct RBasic basic; rb_classext_t *ptr; struct st_table *m_tbl; // メソッド関係一覧 struct st_table *iv_index_tbl; // インスタンス変数一覧 };
20.
st_insert解読 st_insertの定義は呼び出し先の挙動を見たほうが早い 実はループで重複を探して、重複したものが無ければメ ソッド挿入をしているだけ int st_insert(register st_table
*table, register st_data_t key, st_data_t value){ ... for (i = 0; i < table->num_entries; i++) { if ((st_data_t)table->bins[i*2] == key) { table->bins[i*2+1] = (struct st_table_entry*)value; return 1; } .. }
21.
まとめ2 メソッドは構造体st_tableの内側に、配列として 格納されている
22.
Stage3: モジュールのinclude
23.
Kernel#include,Object#extend ● まずObject#extendの呼び出しを手繰ってみる 以下は呼び出し順 rb_define_method(rb_mKernel, "extend",
rb_obj_extend, -1); // eval.c rb_mod_extend_object(VALUE mod, VALUE obj) rb_extend_object(VALUE obj, VALUE module) rb_include_module(VALUE klass, VALUE module)
24.
Kernel#include ● 次にKernel#includeの呼び出しを手繰る ● rb_define_private_method(rb_cModule,
"include", rb_mod_include, -1); // eval.c ● rb_funcall(argv[argc], rb_intern("append_features"), 1, module); ● rb_include_module(VALUE include, VALUE module); // ここでつながる rb_include_module で繋がる 2つは根が同じもの
25.
rb_include_module内約 ● その内側は、実はスーパークラスの指定をしているだけ include_modules_at(VALUE klass,
VALUE c, VALUE module){ /* 色々と事前のチェック */ c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c)); }
26.
Module#prepend ● Ruby2.0で追加されたModule#prependでも似 たようなもの ● ”
” ” ”継承順のリストに 追記 ではなく 挿入 をして いるだけ ● 関数名は書いておくので興味があったら確認 してね ● rb_define_private_method(rb_cModule, "prepend", rb_mod_prepend, -1); // ./eval.c: rb_mod_prepend(int argc, VALUE *argv, VALUE module) rb_prepend_module(VALUE klass, VALUE module)
27.
まとめ3 ● includeはModuleを使った継承 ● Kernel#includeとObject#extendは根っこは同じ ●
Kernel#include、Object#extend、Module#prepe ndって実は継承順序の内側に挟みこみをして いるだけ
28.
Stage4: method_missingの呼ばれ方
29.
method_missing解説 メソッドの呼ばれ方(rb_call0)を探せば簡単 ./vm_eval.c ● static inline
VALUE rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope, VALUE self){ rb_method_entry_t *me = rb_search_method_entry(recv, mid); // method_missingでないメソッド rb_thread_t *th = GET_THREAD(); int call_status = rb_method_call_status(th, me, scope, self); if (call_status != NOEX_OK) { return method_missing(recv, mid, argc, argv, call_status); // ここでmethod_missingを読んでいる } stack_check(); return vm_call0(th, recv, mid, argc, argv, me); }
30.
普通のメソッドの場合 ● メソッド探索のの順を手繰っていくと ● rb_search_method_entry ●
rb_method_entry ● rb_method_entry_get_without_cache ● search_method ● st_lookup(st_table *table, register st_data_t key, st_data_t *value) st_lookupに突き当たる
31.
● そして、st_lookupってdefine_methodの所で見 た!! int st_lookup(st_table
*table, register st_data_t key, st_data_t *value){ ... st_index_t i; for (i = 0; i < table->num_entries; i++) { if ((st_data_t)table->bins[i*2] == key) { if (value !=0) *value = (st_data_t)table->bins[i*2+1]; return 1; } } ...
32.
まとめ ● vm_call0 関数でクラスを指定 ●
Rclass を継承順に沿って探索 ● st_lookup 関数で内部のメソッドを探索 ● st_table 内部にあるメソッドを探す これがrubyのメソッド探索順序
33.
まとめ ● クラスの定義 ● 継承順の定義 ●
メソッドの定義 ● これらを合わせてメソッドの探索順を探した …ことになりましたが
34.
次回の予定 ● もうコレ系のネタやめていいかなと思ってい ますが ネタがない場合、多分構文解析の部分やりま す
35.
大事なこと ● 今までのコード rb_define_method
でメソッド 名でgrep して、そこから手繰る事で、すべて やってこれました ● これだけでruby はほぼ解析可能です
Download