私はC拡張メソッドを使って新しいルビー配列を作成していますが、RARRAY_LENは設定されていません。私は何か間違っているのですか?RARRAY_LENが割り当てられないのはなぜですか?
long int max = 4;
VALUE rAry;
rAry = rb_ary_new2(max);
printf("allocated: %lu\n", RARRAY_LEN(rAry));
出力:
私は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
明らかrb_ary_store(OBJ、インデックスは、valが)RARRAY_LENをインクリメントするために使用される必要があります。非常に重要な方法が基本的に文書化されていないのは奇妙です。 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アレイ値が移入。
これらの関数では、各要素に値を指定する必要があります。だから、を複製してArray.new(4)
とする必要があります。あなたが引数を少なくすると、Rubyで奇妙な動作が起こります。 (例外はありません - 無効なオブジェクトを取得したにもかかわらず)
Cで作成した配列が空だったからです。あなたがそれを入力したのでインクリメントされます。私が投稿した答えの詳細。 – thomthom