# Call rb\_instance\_eval from C code

**URL:** <https://www.ruby-forum.com/t/call-rb-instance-eval-from-c-code/95540>\
**Category:** Ruby\
**Created:** [June 5, 2006, 7:19pm UTC](https://www.ruby-forum.com/t/call-rb-instance-eval-from-c-code/95540 "2006-06-05T19:19:08Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![victor123789](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/f0a364/32.png) [@victor123789](https://www.ruby-forum.com/u/victor123789)\
**Post date:** [June 5, 2006, 7:19pm UTC](https://www.ruby-forum.com/t/call-rb-instance-eval-from-c-code/95540/1 "2006-06-05T19:19:08Z")

</div>

Hi all.

Assuming I have such C code:

VALUE proc; //contains object of class Proc  
VALUE obj; //contains some object

How must look code, corresponding to obj.instance\_eval(&proc) ?

Thanks.

V.

---

<div class="post-metadata">

**Author:** ![victor123789](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/f0a364/32.png) [@victor123789](https://www.ruby-forum.com/u/victor123789)\
**Post date:** [June 5, 2006, 9:14pm UTC](https://www.ruby-forum.com/t/call-rb-instance-eval-from-c-code/95540/2 "2006-06-05T21:14:32Z")

</div>

On Tue, Jun 06, 2006 at 02:16:31AM +0900, Victor S. wrote:

> Assuming I have such C code:
> 
> VALUE proc; //contains object of class Proc  
> VALUE obj; //contains some object
> 
> How must look code, corresponding to obj.instance\_eval(&proc) ?

Hi, Victor.

rb\_funcall(obj, rb\_intern(“instance\_eval”), 1, proc);

\_why

---

<div class="post-metadata">

**Author:** ![victor123789](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/f0a364/32.png) [@victor123789](https://www.ruby-forum.com/u/victor123789)\
**Post date:** [June 5, 2006, 9:45pm UTC](https://www.ruby-forum.com/t/call-rb-instance-eval-from-c-code/95540/3 "2006-06-05T21:45:49Z")

</div>

On Tue, Jun 06, 2006 at 04:12:14AM +0900, why the lucky stiff wrote:

> rb\_funcall(obj, rb\_intern(“instance\_eval”), 1, proc);  
> I don’t think that will work: proc is not a String but a Proc  
> (TypeError).

See [ruby-talk:180647] and [ruby-talk:188958].

---

<div class="post-metadata">

**Author:** ![victor123789](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/f0a364/32.png) [@victor123789](https://www.ruby-forum.com/u/victor123789)\
**Post date:** [June 5, 2006, 10:43pm UTC](https://www.ruby-forum.com/t/call-rb-instance-eval-from-c-code/95540/4 "2006-06-05T22:43:46Z")

</div>

On Tue, Jun 06, 2006 at 04:43:10AM +0900, Mauricio F. wrote:

> On Tue, Jun 06, 2006 at 04:12:14AM +0900, why the lucky stiff wrote:
> 
> > rb\_funcall(obj, rb\_intern(“instance\_eval”), 1, proc);
> 
> I don’t think that will work: proc is not a String but a Proc (TypeError).
> 
> See [ruby-talk:180647] and [ruby-talk:188958].

Ohhhh. I guess define\_method can take a proc, though. Back to ye olde  
cloaker.  
Based on Guy’s example:

wagon$ cat a.c  
#include \<ruby.h\>

static VALUE  
rb\_proc\_bind(VALUE obj, VALUE a)  
{  
VALUE meth, meta;  
VALUE cloaker = ID2SYM(rb\_intern(“ **cloaker** ”));  
meta = rb\_singleton\_class(obj);  
rb\_funcall(meta, rb\_intern(“define\_method”), 2, cloaker, a);  
meth = rb\_funcall(meta, rb\_intern(“instance\_method”), 1, cloaker);  
rb\_funcall(meta, rb\_intern(“remove\_method”), 1, cloaker);  
return rb\_funcall(meth, rb\_intern(“bind”), 1, obj);  
}

VALUE  
obj\_eval\_it(int argc, VALUE \*argv, VALUE self)  
{  
VALUE meth, proc;  
rb\_scan\_args(argc, argv, “0&”, &proc);

```
  /* !^! here is your rb_instance_eval replacement, victor. !^! */
  meth = rb_proc_bind(self, proc);
  return rb_funcall(meth, rb_intern("call"), 0);

```

}

void Init\_a()  
{  
VALUE obj = rb\_funcall(rb\_cObject, rb\_intern(“new”), 0);  
rb\_define\_method(rb\_cObject, “eval\_it”, obj\_eval\_it, -1);  
rb\_const\_set(rb\_cObject, rb\_intern(“OBJ”), obj);  
}

wagon$ ruby -ra -e ‘p Object::OBJ; Object::OBJ.eval\_it { @b = 12 }; p  
Object::OBJ’  
#Object:0x80768dc  
#\<Object:0x80768dc @b=12\>

But now I really don’t understand specific\_eval().

\_why

---

<div class="post-metadata">

**Author:** ![victor123789](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/f0a364/32.png) [@victor123789](https://www.ruby-forum.com/u/victor123789)\
**Post date:** [June 6, 2006, 3:51pm UTC](https://www.ruby-forum.com/t/call-rb-instance-eval-from-c-code/95540/5 "2006-06-06T15:51:24Z")

</div>

From: why the lucky stiff [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Monday, June 05, 2006 11:40 PM

> cloaker.  
> meta = rb\_singleton\_class(obj);  
> rb\_scan\_args(argc, argv, “0&”, &proc);  
> rb\_const\_set(rb\_cObject, rb\_intern(“OBJ”), obj);  
> }
> 
> wagon$ ruby -ra -e ‘p Object::OBJ; Object::OBJ.eval\_it { @b = 12 }; p  
> Object::OBJ’  
> #Object:0x80768dc  
> #\<Object:0x80768dc @b=12\>
> 
> But now I really don’t understand specific\_eval().

Thanks why! Would try this.

Victor.

---

<div class="post-metadata">

**Author:** ![victor123789](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/f0a364/32.png) [@victor123789](https://www.ruby-forum.com/u/victor123789)\
**Post date:** [June 7, 2006, 1:18pm UTC](https://www.ruby-forum.com/t/call-rb-instance-eval-from-c-code/95540/6 "2006-06-07T13:18:02Z")

</div>

On Tue, Jun 06, 2006 at 05:40:12AM +0900, why the lucky stiff wrote:

> wagon$ cat a.c  
> rb\_funcall(meta, rb\_intern(“remove\_method”), 1, cloaker);  
> return rb\_funcall(meth, rb\_intern(“bind”), 1, obj);  
> }

Nice hack 🙂  
Just for fun, here’s another idea:

```
$ cat ieval.c

#include <ruby.h>

static VALUE instance_eval_proc;

static VALUE
do_instance_eval(VALUE obj, VALUE proc)
{
  return rb_funcall(instance_eval_proc, rb_intern("call"), 2, obj, 

```

proc);  
}

```
VALUE
obj_eval_it(int argc, VALUE *argv, VALUE self)
{
  VALUE meth, proc;
  rb_scan_args(argc, argv, "0&", &proc);

  return do_instance_eval(self, proc);
}

void Init_ieval()
{
  VALUE obj;

  instance_eval_proc = rb_eval_string("lambda{|o,b| 

```

o.instance\_eval(&b)}");  
obj = rb\_funcall(rb\_cObject, rb\_intern(“new”), 0);  
rb\_define\_method(rb\_cObject, “eval\_it”, obj\_eval\_it, -1);  
rb\_const\_set(rb\_cObject, rb\_intern(“OBJ”), obj);  
}

```
$ ruby -rieval -e 'p Object::OBJ; Object::OBJ.eval_it { @b = 12 }; p 

```

Object::OBJ’  
#Object:0xb7e13e14  
#\<Object:0xb7e13e14 @b=12\>

One can still hope matz’s reflection ([180647] again) will bring a more  
convenient way to do that, though 😉

---

<div class="post-metadata">

**Author:** ![victor123789](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/f0a364/32.png) [@victor123789](https://www.ruby-forum.com/u/victor123789)\
**Post date:** [June 8, 2006, 12:04am UTC](https://www.ruby-forum.com/t/call-rb-instance-eval-from-c-code/95540/7 "2006-06-08T00:04:37Z")

</div>

From: Mauricio Julio Fernandez Pradier [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
On  
Behalf Of Mauricio F.  
Sent: Wednesday, June 07, 2006 2:15 PM

> cloaker.
> 
> > ```
> > meta = rb_singleton_class(obj);
> > 
> > ```
> 
> ```
> $ cat ieval.c
> }
> void Init_ieval()
> $ ruby -rieval -e 'p Object::OBJ; Object::OBJ.eval_it { @b = 12 }; p
> 
> ```
> 
> Object::OBJ’  
> #Object:0xb7e13e14  
> #\<Object:0xb7e13e14 @b=12\>

Thanks Mauricio! Something like this I’ve already invented 🙂 Generally,  
almost any feature we can’t conveniently use from C, colud be used with  
evaluating some string.

> One can still hope matz’s reflection ([180647] again) will bring a more  
> convenient way to do that, though 😉

It would be the most straightforward way. When it would.

Matz? 🙂

V.
