我正在使用 C 扩展方法创建一个新的 ruby 数组,但没有设置 RARRAY_LEN。难道我做错了什么?
long int max = 4;
VALUE rAry;
rAry = rb_ary_new2(max);
printf("allocated: %lu\n", RARRAY_LEN(rAry));
输出:
allocated: 0
我正在使用 C 扩展方法创建一个新的 ruby 数组,但没有设置 RARRAY_LEN。难道我做错了什么?
long int max = 4;
VALUE rAry;
rAry = rb_ary_new2(max);
printf("allocated: %lu\n", RARRAY_LEN(rAry));
输出:
allocated: 0
从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_new3
或rb_ary_new4
。
来自Programming Ruby: The Pragmatic Programmer's Guide:
VALUE rb_ary_new3(long length, ...")
返回一个新Array
的给定长度并填充剩余的参数。
VALUE rb_ary_new4(long length, VALUE *values")
返回一个新Array
的给定长度并填充 C 数组值。
请注意,这些函数要求您为每个元素提供一个值。因此,您需要执行以下操作:rAry = rb_ary_new3(4, Qnil, Qnil, Qnil, Qnil)
复制Array.new(4)
. 如果你提供的参数较少,你会在 Ruby 中得到奇怪的行为。(没有例外——尽管你得到了一个无效的对象。)
显然需要使用 rb_ary_store(obj, index, val) 来增加 RARRAY_LEN。奇怪的是,如此重要的方法基本上没有记录。