Calling instance_eval on a block in C


#1

If I have this ruby method:

def eval_it(obj, &b)
obj.instance_eval(&b)
end

How do write the C code to make this happen? If I do this:

rb_funcall(obj, rb_intern(“instance_eval”), 1, zz);

Ruby is apparently expecting a String for the type of zz.

Any ideas?

Thanks!
-John
http://www.iunknown.com


#2

On Apr 14, 2006, at 10:33 AM, John L. wrote:

Ruby is apparently expecting a String for the type of zz.
Hey John,

I’m not positive, but I don’t think it is possible, because of the
block. Blocks come in through manipulated ruby_frames, even if they
look like they are passed in via shells. Clues being:

static VALUE
rb_f_block_given_p()
{
if (ruby_frame->prev && ruby_frame->prev->iter == ITER_CUR &&
ruby_block)
return Qtrue;
return Qfalse;
}

and the first hunk of specific_eval reading:

 if (rb_block_given_p()) {
     if (argc > 0) {
         rb_raise(rb_eArgError, "wrong number of arguments (%d

for 0)", argc
);
}
return yield_under(klass, self);
}


#3

I think you’re right. I’ve tried all sorts of combinations before
posting
this plea for help :slight_smile:

Now I have to turn this method that I’ve been writing all morning
inside-out
since I can’t make this happen … yuck.

Thanks for looking around!
-John
http://www.iunknown.com

Hey John,


#4

“J” == John L. removed_email_address@domain.invalid writes:

J> def eval_it(obj, &b)
J> obj.instance_eval(&b)
J> end

moulon% cat a.c
#include <ruby.h>

static VALUE
a_eval_it(VALUE obj, VALUE a)
{
return rb_obj_instance_eval(0, 0, a);
}

void Init_a()
{
VALUE a_cA = rb_define_class(“A”, rb_cObject);
rb_define_method(a_cA, “eval_it”, a_eval_it, 1);
}
moulon%

moulon% ruby -ra -e ‘b = Object.new; A.new.eval_it(b) {p self; @b = 12};
p b’
#Object:0xb7d5ec8c
#<Object:0xb7d5ec8c @b=12>
moulon%

Guy Decoux


#5

THANK YOU!!!

You have saved me from probably a good week’s worth of hell (aka C++). I
spent a lot of time building up my abstractions in RubyCLR so that all
of
the nasty marshaling / interop goo generation stuff was handled in Ruby.
Without your solution, I would have had to re-implement about half of
those
abstractions in raw C++, which probably would have taken me at least
another
week to implement.

Let me know if we’re ever in the same city - I definitely owe you dinner
for
this one :slight_smile:

Cheers,
-John
http://www.iunknown.com


#6

On Sat, Apr 15, 2006 at 03:02:55AM +0900, Ryan D. wrote:

Ruby is apparently expecting a String for the type of zz.

I’m not positive, but I don’t think it is possible, because of the
block.

See [ruby-talk:180647].