2011-06-28 103 views
4

我正在使用C擴展方法來創建一個新的紅寶石數組,但RARRAY_LEN沒有被設置。難道我做錯了什麼?爲什麼RARRAY_LEN沒有被分配?

long int max = 4; 
VALUE rAry; 

rAry = rb_ary_new2(max); 
printf("allocated: %lu\n", RARRAY_LEN(rAry)); 

輸出:

allocated: 0 

回答

0

顯然rb_ary_store(OBJ,索引,val)的需要被用於遞增RARRAY_LEN。奇怪的是,一個如此重要的方法基本上沒有記錄。

+0

這是因爲你在C中創建的數組是空的 - 它只是爲4個項目分配了內存。它是因爲你填充它而增加的。在我發佈的答案更多細節。 – thomthom

2

array.c(紅寶石1.8.6): #define RARRAY_LEN(s) (RARRAY(s)->len)

RARRAY(s)->len相同Array#length

rb_ary_new2(4)Array.new(4)不一樣。

VALUE 
rb_ary_new2(len) 
    long len; 
{ 
    return ary_new(rb_cArray, len); 
} 

VALUE 
rb_ary_new() 
{ 
    return rb_ary_new2(ARY_DEFAULT_SIZE); 
} 

ARY_DEFAULT_SIZE定義爲16

什麼是隻爲數組分配內存 - 但不填充它。當您知道數組的最終大小時使用它,因此不必動態調整大小。

你想用於你的意圖的是rb_ary_new3rb_ary_new4

Programming Ruby: The Pragmatic Programmer's Guide

VALUE rb_ary_new3(long length, ...")
返回給定長度的新Array並填充了剩餘的參數。

VALUE rb_ary_new4(long length, VALUE *values")
返回給定長度和填充與C數組值的新Array

請注意,這些函數要求您爲每個元素提供一個值。因此,您需要執行以下操作:rAry = rb_ary_new3(4, Qnil, Qnil, Qnil, Qnil)以複製Array.new(4)。如果你提供的參數較少,你會在Ruby中出現奇怪的行爲。 (沒有例外 - 儘管事實上你得到了一個無效的對象。)