讀完ruby hacking guide第6章,徹底總結(jié)下:
1.在Ruby中,類(lèi)也是一個(gè)對(duì)象,因此有實(shí)例變量。類(lèi)的實(shí)例變量、類(lèi)變量、常量都是存儲(chǔ)在RClass struct的iv_tbl中,
struct RClass {
struct RBasic basic;
struct st_table *iv_tbl;
struct st_table *m_tbl;
VALUE super;
};
iv_tbl的類(lèi)型是st_table,我在
這里用java實(shí)現(xiàn)了一下。
2.用戶(hù)自定義類(lèi)的對(duì)象(ruby層次聲明的類(lèi)的對(duì)象)的實(shí)例變量存儲(chǔ)在RObject struct的iv_tbl中,
struct RObject {
struct RBasic basic;
struct st_table *iv_tbl;
};
調(diào)用方法,本質(zhì)上是一個(gè)查表操作。buildin的幾個(gè)類(lèi),比如String、Array、Hash等(在c層次上實(shí)現(xiàn)的類(lèi)),它們的結(jié)構(gòu)并沒(méi)有iv_table,這是從節(jié)省內(nèi)存空間的角度考慮,它們的實(shí)例變量存儲(chǔ)在一張全局的st_table中。這張表比較特別,其中的每一個(gè)對(duì)應(yīng)的值又是一個(gè)st_table,也就是一個(gè)“二元結(jié)構(gòu)”,第一層結(jié)構(gòu)是類(lèi)名與實(shí)例變量表的映射,第二層才是實(shí)例變量名與實(shí)際值的映射。
3.全局變量存儲(chǔ)在一張全局的st_table中,這個(gè)表的鍵就是變量名ID,由于全局變量允許通過(guò)alias來(lái)設(shè)置別名,因此這張全局表中真正存儲(chǔ)的是下面這個(gè)struct
334 struct global_entry {
335 struct global_variable *var;
336 ID id;
337 };
324 struct global_variable {
325 int counter; /* 引用計(jì)數(shù) */
326 void *data; /* 變量值 */
327 VALUE (*getter)(); /* 取值函數(shù) */
328 void (*setter)(); /* 設(shè)置函數(shù) */
329 void (*marker)(); /* 標(biāo)記函數(shù) */
330 int block_trace;
331 struct trace_var *trace;
332 };
(variable.c)
當(dāng)不同變量名(通過(guò)別名聲明)指向的是同一個(gè)全局變量,其實(shí)它們指向的是同一個(gè)struct global_variable。