4

我正在使用 C 扩展方法创建一个新的 ruby​​ 数组,但没有设置 RARRAY_LEN。难道我做错了什么?

long int max = 4;
VALUE rAry;

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

输出:

allocated: 0
4

2 回答 2

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")
返回一个新Array的给定长度并填充 C 数组值。

请注意,这些函数要求您为每个元素提供一个值。因此,您需要执行以下操作:rAry = rb_ary_new3(4, Qnil, Qnil, Qnil, Qnil)复制Array.new(4). 如果你提供的参数较少,你会在 Ruby 中得到奇怪的行为。(没有例外——尽管你得到了一个无效的对象。)

于 2012-03-19T13:46:30.387 回答
0

显然需要使用 rb_ary_store(obj, index, val) 来增加 RARRAY_LEN。奇怪的是,如此重要的方法基本上没有记录。

于 2011-06-28T18:45:11.763 回答