On Tue, Jun 06, 2006 at 05:40:12AM +0900, why the lucky stiff wrote:
> On Tue, Jun 06, 2006 at 04:43:10AM +0900, Mauricio Fernandez 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).
> > 
>
> 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);
>   }

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 ;)

-- 
Mauricio Fernandez  -   http://eigenclass.org   -  singular Ruby