Fredrik Jagenheim wrote: > > I can't get this simple thing to work. My extension uses two > functions, 'add_value' and 'add_values'. 'add_value' takes one value > and 'add_values' takes an array of values. > > The idea is to have add_values to call add_value for each of the > values. Simple enough... > > static VALUE add_value(VALUE self, VALUE val) > { > # Code that works > } > > static VALUE add_values(VALUE self, VALUE vals) > { > rb_iterate(rb_each, vals, add_value, 0); > } > > 'add_value' works fine, but when I call 'add_values', I get this: > TypeError: wrong argument type String (expected Data) > You don't show how you defined 'add_values' or how you're calling it from Ruby, but I think your initial array is in 'self' ... .... 'vals' could contain garbage ? Here's an example from enum.c (Enumerable#reject) with some printf() statements added. /* this line from later in enum.c */ rb_define_method(rb_mEnumerable,"reject", enum_reject, 0); static VALUE reject_i(i, ary) VALUE i, ary; { printf("debug; i == %s\n", RSTRING(rb_inspect(i))->ptr); if (!RTEST(rb_yield(i))) { printf("debug; saving %s\n", RSTRING(rb_inspect(i))->ptr); rb_ary_push(ary, i); } return Qnil; } static VALUE enum_reject(obj) /* -- Enumerable#reject -- */ VALUE obj; { VALUE ary = rb_ary_new(); printf("debug; iter >>\n"); rb_iterate(rb_each, obj, reject_i, ary); printf("debug; << iter\n"); return ary; } #------------------- # # Ruby: # Array#reject doesn't use rb_iterate, so # contrive to use Enumerable#reject which # has the debug statements. class MyArr include Enumerable def initialize(*args) @arr = Array.new(args) end # Enumerable mix-in needs MyArr#each def each # Use Array#each @arr.each {|e| yield e} end end enum = MyArr.new(5,7,1,3,9,2) p enum.reject{|val| val > 5} #-> [5, 1, 3, 2] #-> debug; iter >> #-> debug; i == 5 #-> debug; saving 5 #-> debug; i == 7 #-> debug; i == 1 #-> debug; saving 1 #-> debug; i == 3 #-> debug; saving 3 #-> debug; i == 9 #-> debug; i == 2 #-> debug; saving 2 #-> debug; << iter #-> [5, 1, 3, 2] :daz