ruby0.49 array.c源碼閱讀

ruby0.49 array.c源碼閱讀
我想,應該叫源碼閱讀,自己隨心所欲的讀。就像讀小說一樣。因爲我比較喜歡ruby語言,讀新版本的,代碼量太大,不划算。爲此,找了最早版本的。代碼量少些。
讀array.c源碼,今天基本上把代碼過完了,而且基本都理解了。
數組中,好像有三個重要的要素
arr->len 存儲數組中實際的元素個數,下標從0開始。
arr->capa 存儲數組中,目前分配的空間大小。
arr->ptr 存儲數組的首地址。
初始化的函數有好幾個
ary_new2
ary_new
ary_new3
ary_new4
這幾個都是與初始化相關,而編譯時,就通不過。如何修改,沒搞定。
assoc_new
fary_new
還是與初始化相關。
astore(ary,idx,val)
這個函數看懂了。完成的事
ary[idx]=val
其中當分配空間不夠時,需要擴充。另外,如果idx大於數組的長度,需要把數組長度改大,並且增長的數組元素給默認值0。
fary_push
fary_append
fary_pop
fary_shift
fary_unshift
ary_entry
這幾個函數都比較好懂。matz的代碼寫得很平實,基本上都用的是最樸實的想法,把代碼功能實現。
ary_subseq
好像是從一個數組中取出子數組來。
range_beg_end
沒看懂
fary_aref
好像也是取子數組。
fary_each
對每個元素調用塊函數,這個寫法和ruby很像,只是不知道作者如何實現的。

static VALUE
Fary_plus(x, y)
    struct RArray *x, *y;
{
    struct RArray *z;

    switch (TYPE(y)) {
      case T_ARRAY:
        //a=[1,2,3],b=[4,5],a+b==[1,2,3,4,5]
    z = (struct RArray*)ary_new2(x->len + y->len);
    memcpy(z->ptr, x->ptr, x->len*sizeof(VALUE));
    memcpy(z->ptr+x->len, y->ptr, y->len*sizeof(VALUE));
    z->len = x->len + RARRAY(y)->len;
    break;

      default:
  //這個分支a=[1,2,3],a+10報錯了,需要調試
    GC_LINK;
    GC_PRO3(z, (struct RArray*)Fary_clone(x));
    Fary_push(z, y);
    GC_UNLINK;
    break;
    }
    return (VALUE)z;
}
這個函數比較有意思。我看作者的意思是
a=[1,2,3],b=[4,5]
a+b===[1,2,3,4,5]
a+10===[1,2,3,10]
可惜我的最新的ruby中調試時,a+10報錯了。如果能調試就好了。

//a=[1,2,3],a*3=[1,2,3,1,2,3,1,2,3]
static VALUE
Fary_times(ary, times)
    struct RArray *ary;
    VALUE times;
{
    struct RArray *ary2;
    int i, len;

    len = NUM2INT(times) * ary->len;
    ary2 = (struct RArray*)ary_new2(len);
    ary2->len = len;

    for (i=0; i<len; i+=ary->len) {
    memcpy(ary2->ptr+i, ary->ptr, ary->len*sizeof(VALUE));
    }

    return (VALUE)ary2;
}
這個函數也有意思,如
a=[1,2,3],a*3=[1,2,3,1,2,3,1,2,3]
作者的寫法,就是一段段的複製。作者使用mem*函數很熟練,我看到mem函數,還是在《程序設計實踐》中看人第一次使用mem函數。
總之,這個array.c還是很容易看的。沒有很複雜的算法,寫得通俗易懂。
本來,我想,自己功力還不夠,也許先看小一些的程序,但覺得ruby很好玩。一直捨棄不下,於是接着讀。
如果能編譯出來,就太好了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章