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(Ruby 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です。

Ruby のプログラミング: The Pragmatic Programmer's Guideから:

VALUE rb_ary_new3(long length, ...")
Array指定された長さ の new を返し、残りの引数が取り込まれます。

VALUE rb_ary_new4(long length, VALUE *values")
Array指定された長さ の new を返し、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 に答える