I have arrays in Ruby and I would like to extend them with .normalize method. This method should modify array such that all it`s elements sum up to 1. This is way too expensive in Ruby, so I want to do it in C with RubyInline.
require "rubygems"
require "inline"
class Array
inline do |builder|
builder.c_raw '
static VALUE normalize(VALUE self) {
double total_size = 0, len;
int i;
VALUE* array = RARRAY_PTR(self);
len = RARRAY_LEN(self);
for(i=0; i < len; i++){
total_size += NUM2DBL(array[i]);
}
for(i=0; i < len; i++){
array[i] = INT2NUM(NUM2DBL(array[i])/total_size);
}
return array;
}'
end
end
a = [1,2,0,0,0,0,0,3,0,4]
puts a.normalize.inspect
This results in
$ ruby tmp.rb
tmp.rb:29: [BUG] Segmentation fault
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]
Aborted (core dumped)
EDIT: after some debugging, crash seems to come at
VALUE* array = RARRAY_PTR(self);
gem install inline. Running your script :undefined method 'inline' for Array:Class (NoMethodError). Checked the RDoc for this gem, no inline method. Seems to be an editor, not a C compiler.gem install RubyInline.RARRAY(<array>) -> ptr). I'm not sure ifCheck_Type(self, T_ARRAY);is still valid. If I put it at the beginning of the block ==>in 'normalize': wrong argument type false (expected Array) (TypeError)