Forum: Ruby Calling instance_eval on a block in C

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
John L. (Guest)
on 2006-04-14 21:35
(Received via mailing list)
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
Ryan D. (Guest)
on 2006-04-14 22:03
(Received via mailing list)
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);
     }
John L. (Guest)
on 2006-04-14 22:31
(Received via mailing list)
I think you're right. I've tried all sorts of combinations before
posting
this plea for help :)

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,
Mauricio F. (Guest)
on 2006-04-15 00:40
(Received via mailing list)
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].
ts (Guest)
on 2006-04-15 13:45
(Received via mailing list)
>>>>> "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
John L. (Guest)
on 2006-04-18 01:26
(Received via mailing list)
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 :)

Cheers,
-John
http://www.iunknown.com
This topic is locked and can not be replied to.