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