Reputation: 12466
arr=Array.new(3)
arr[0]=5
arr[1]=3
arr[2]=2
These lines should call this function, https://github.com/ruby/ruby/blob/trunk/array.c#L568 according to this, http://www.ruby-doc.org/core-1.9.3/Array.html
So I have added couple of lines there to display the values of array. But i didn't get the expected result.
else {
memfill(RARRAY_PTR(ary), len, val);
ARY_SET_LEN(ary, len);
int i;
int result;
result = 0;
VALUE *s_arr = RARRAY_PTR(ary);
for(i = 0; i < len; i++) {
result = LONG2NUM(s_arr[i]);
printf("r: %d\n",result);
}
}
I got the result like this:
arr=Array.new(3)
arr[0]=5
arr[1]=3
arr[2]=2
r: 9
r: 9
r: 9
Why is this result? Why 9?
I have followed these to solve it:
Can anyone please help to display/printf the value of Ruby array in C?
Upvotes: 0
Views: 200
Reputation: 434745
This doesn't make any sense:
result = LONG2NUM(s_arr[i]);
LONG2NUM
is used to convert a C long int
to a Ruby VALUE
that holds a number; s_arr[i]
is already a VALUE
so you're effectively doing things like VALUE v = LONG2NUM((VALUE)5)
. LONG2NUM
is defined in ruby.h
as a wrapper for this:
#define LONG2NUM_internal(v) (FIXABLE(v) ? LONG2FIX(v) : rb_int2big(v))
and if v
fits in a VALUE
without converting it to a bignum, then you end up using this:
#define INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<1 | FIXNUM_FLAG))
So you're basically doing a bunch of bit wrangling on a pointer and wondering why it always says 9
; consider yourself lucky (or unlucky) that it doesn't say segmentation fault.
You want to convert a VALUE
which holds a number to a C integer. You probably want to use FIX2LONG
:
#define FIX2LONG(x) (long)RSHIFT((SIGNED_VALUE)(x),1)
or NUM2LONG
:
#define NUM2LONG_internal(x) ((long)(FIXNUM_P(x) ? FIX2LONG(x) : rb_num2long(x)))
#ifdef __GNUC__
#define NUM2LONG(x) \
__extension__ ({VALUE num2long_x = (x); NUM2LONG_internal(num2long_x);})
#else
static inline long
NUM2LONG(VALUE x)
{
return NUM2LONG_internal(x);
}
#endif
So something like this:
long result;
for(i = 0; i < len; i++) {
result = NUM2LONG(s_arr[i]);
printf("r: %ld\n", result);
}
Note the switch to %ld
since we're using long
s now and we always turn on all the picky compiler flags that complain about mismatched printf
formats and arguments. Of course, this assumes that you are certain that the array contains numbers that will fit in a C long
.
Upvotes: 0