I'd been wanting to mess with writing ruby extensions so I wrote the
whole thing in c. I do realize one thing already: I'm using the
'entries' method to pull out what to iterate over instead of each. This
comes from something that I'm totally clear on: The contract for the
method is that we receive in an Enumrable object so can we assume that
this method will be implemented since it's part of the Enumerable
mixin? Anyways here's the code:

#include "ruby.h"

static ID id_entries;
typedef struct _gen
{
    int curr;
    VALUE values;
} Generator;

//Is there a built in way to do this?
#define TEST(t) t?Qtrue:Qfalse

static VALUE t_init(int argc, VALUE *argv, VALUE self)
{
    Generator* gen;
    Data_Get_Struct(self, Generator, gen);
    if(argc > 0)
    {
        VALUE arr = rb_funcall(argv[0], id_entries, 0);
        gen->values = arr;
    }
    else
    {
        VALUE arr = rb_ary_new();
        gen->values = arr;
        rb_yield(self);
    }
    gen->curr = 0;
    return self;
}

static VALUE t_end_q(VALUE self)
{
    Generator* gen;
    Data_Get_Struct(self, Generator, gen);
    int size = RARRAY(gen->values)->len;
    int curr = gen->curr;
    return TEST(curr >= size);
}

static VALUE t_next_q(VALUE self)
{
    return TEST(!t_end_q(self));
}

static VALUE t_pos(VALUE self)
{
    Generator* gen;
    Data_Get_Struct(self, Generator, gen);
    int curr = gen->curr;
    return INT2NUM(curr);
}

static VALUE t_rewind(VALUE self)
{
    Generator* gen;
    Data_Get_Struct(self, Generator, gen);
    gen->curr = 0;
    return self;
}

static VALUE t_yield(VALUE self, VALUE element)
{
    Generator* gen;
    Data_Get_Struct(self, Generator, gen);
    rb_ary_push(gen->values, element);
    return gen->values;
}

static VALUE t_current(VALUE self)
{
    if(t_end_q(self))
    {
        rb_raise(rb_eEOFError, "no more elements available");
        return Qnil;
    }
    Generator* gen;
    Data_Get_Struct(self, Generator, gen);
    int curr = gen->curr;
    return rb_ary_entry(gen->values, curr);
}

static VALUE t_next(VALUE self)
{
    if(t_end_q(self))
    {
        rb_raise(rb_eEOFError, "no more elements available");
        return Qnil;
    }
    Generator* gen;
    Data_Get_Struct(self, Generator, gen);
    int curr = gen->curr++;
    VALUE temp = rb_ary_entry(gen->values, curr);
    return temp;
}

static VALUE t_each(VALUE self)
{
    Generator* gen;
    Data_Get_Struct(self, Generator, gen);
    gen->curr = 0;
    rb_iterate(rb_each, gen->values, rb_yield, 0);
    return self;
}

static void gen_free(void* p)
{
    free(p);
}

static void gen_mark(void* p)
{
    Generator* g = p;
    rb_gc_mark(g->values);
}

static VALUE gen_alloc(VALUE klass)
{
    Generator* gen = malloc(sizeof(Generator));
    VALUE obj;
    obj = Data_Wrap_Struct(klass, gen_mark, gen_free, gen);
    return obj;
}

VALUE cGen;
void Init_generator_j()
{
    id_entries = rb_intern("entries");
    cGen = rb_define_class("GeneratorJ", rb_cObject);
    rb_define_method(cGen, "initialize", t_init, -1);
    rb_define_method(cGen, "next?", t_next_q, 0);
    rb_define_method(cGen, "next", t_next, 0);
    rb_define_method(cGen, "end?", t_end_q, 0);
    rb_define_method(cGen, "pos", t_pos, 0);
    rb_define_method(cGen, "index", t_pos, 0);
    rb_define_method(cGen, "rewind", t_rewind, 0);
    rb_define_method(cGen, "yield", t_yield, 1);
    rb_define_method(cGen, "current", t_current, 0);
    rb_define_method(cGen, "each", t_each, 0);

    rb_define_alloc_func(cGen, gen_alloc);
}

I haven't written much c in a long while (let alone ruby in c) so be
kind. It doesn't seem to be much of a speed improvement at all over the
same code written in straight ruby, but it was educational for me.

I did mess with trying to get infinite generators to work, but I
cheated and looked at the code after a bit so I was tainted after that.
Here is a test case I made however if it's of any use. (require
'matrix' of course):

    def fib(n) (Matrix[[1,1],[1,0]]**(n-1))[0,0] end
    def test_fib
        g = Generator.new do |g|
            a, b = 0, 1
            while true
                g.yield a
                a, b = b, a+b
            end
        end
        100.times do |i|
            assert_equal(i, g.pos)
            assert_equal(fib(i), g.next)
        end
    end

Thanks!

-----Horndude77