A list of usefull codes and tips for C Ruby api.
MyStruct * data;
Data_Get_Struct(self, MyStruct, data);
MyStruct * data = malloc(sizeof(MyStruct));
return Data_Wrap_Struct(self, FUNC_MyStruct_mark, FUNC_MyStruct_free, data);
rb_define_method(rb_cKlass, "method", FUNC_KLASS_method, 0);
VALUE FUNC_KLASS_method(VALUE self) {
MyStruct * data;
Data_Get_Struct(self, MyStruct, data);
// Do something
return VALUE;
}
rb_define_method(rb_cKlass, "method", FUNC_KLASS_method, 2);
VALUE FUNC_KLASS_method(VALUE self, VALUE arg1, VALUE arg2) {
MyStruct * data;
Data_Get_Struct(self, MyStruct, data);
// Do something
return VALUE;
}
rb_define_method(rb_cKlass, "method", FUNC_KLASS_method, -1);
VALUE FUNC_KLASS_method(int argc, VALUE* argv, VALUE self) {
MyStruct * data;
Data_Get_Struct(self, MyStruct, data);
VALUE arg1, arg2, arg3, arg4;
rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4); // 1 normal argument and 3 optional arguments
if(NIL_P(arg2))
// Don't forget to check optional arguments
// Do something
return VALUE;
}
NIL_P(VALUE); // nil
FIXNUM_P(VALUE); // fixnum
RB_FLOAT_TYPE_P(VALUE); // float
SYMBOL_P(VALUE); // symbol
RTEST(VALUE); // true or false
RB_TYPE_P(VALUE, T_TYPE); // other builtin types
RBASIC_CLASS(VALUE) == rb_cKlass // other classes
#define RB_CHECK_KLASS(o,k) (RBASIC_CLASS(o) == k)
Creates an empty array with size 0.
VALUE ary = rb_ary_new();
rb_ary_push(ary, VALUE);
// ...
Creates an empty array with a default size.
int length = 10;
VALUE ary = rb_ary_new2(length);
// ...
Creates an array of defined VALUEs.
int length = 2;
VALUE ary = rb_ary_new3(length, VALUE el1, VALUE el2);
// ...
Creates an array from a C array of VALUEs.
int length = 2;
VALUE ary_c[2] = {VALUE, VALUE};
VALUE ary = rb_ary_new4(length, ary_c);
// or...
int length = 2;
VALUE ary = rb_ary_new4(length, (VALUE[2]){VALUE, VALUE});
// or...
int length = 2;
VALUE ary = rb_ary_new_from_values(length, (VALUE[2]){VALUE, VALUE}); // alias for rb_ary_new4
Note: there is no real performance impact between rb_ary_new3
and rb_ary_new4
.
VALUE ary1 = rb_ary_new();
VALUE ary2 = rb_ary_dup(ary1);
RARRAY_LEN(VALUE) # returns length in C
Stores a VALUE in an array at defined index. Note that negative indexes count from the end of the specified array.
rb_ary_store(VALUE ary, long index, VALUE element);
Appends an element at the end of the array.
rb_ary_push(VALUE ary, VALUE element);
Prepends an element at the start of the array.
rb_ary_unshift(VALUE ary, VALUE element);
Gets the element at defined index. Note that negative indexes count from the end of the specified array.
rb_ary_entry(VALUE ary, long index);
Removes the last element of the array.
rb_ary_pop(VALUE ary);
Removes the first element of the array.
rb_ary_shift(VALUE ary);
Removes the element of the array at defined index. If index is out of bounds, returns Qnil
. Otherwise, returns the deleted element. Note that negative indexes count from the end of the specified array.
rb_ary_delete_at(VALUE ary, long index);
Removes all the elements in the array that are equal to specified item. Returns Qnil
if no matches are found. Note that the item can be a block.
rb_ary_delete(VALUE ary, VALUE item_to_delete);
rb_ary_delete(VALUE ary, VALUE block);
Deletes all elements from the array.
rb_ary_clear(VALUE ary);
Retrieving elements in an array is a time-consuming process. It's more efficient to store an element in a VALUE and then to use it if we need it more than one time.
// Less efficient
VALUE ary = rb_ary_new();
rb_ary_push(ary, INT2FIX(10));
int val = FIXNUM_P(rb_ary_entry(ary, 0)) ? FIX2INT(rb_ary_entry(ary, 0)) : 0;
// More efficient
VALUE ary = rb_ary_new();
VALUE tmp = rb_ary_push(ary, INT2FIX(10));
int val = FIXNUM_P(tmp) ? FIX2INT(tmp) : 0;
VALUE sym = ID2SYM(rb_intern("symbol"));
VALUE sym = ID2SYM(rb_intern_str(VALUE));