# Instance\_eval, yield, C extensions

**URL:** <https://www.ruby-forum.com/t/instance-eval-yield-c-extensions/66718>\
**Category:** Ruby\
**Created:** [August 28, 2006, 6:43pm UTC](https://www.ruby-forum.com/t/instance-eval-yield-c-extensions/66718 "2006-08-28T18:43:30Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [August 28, 2006, 6:43pm UTC](https://www.ruby-forum.com/t/instance-eval-yield-c-extensions/66718/1 "2006-08-28T18:43:30Z")

</div>

Hi all,

How do I write the code below within a C extension? I’ve seen a few  
threads  
about it (including ruby-talk: 86105) but I’m just not “getting it”.

# Assume Foo is a subclass of String

module Kernel  
def my\_meth  
instance\_eval{ Foo.new(yield) }  
end  
end

With that I can do my\_meth{ “some\_string” } and get back a String  
object.

I tried this:

static VALUE foo\_block(VALUE self){  
return rb\_funcall(cFoo, rb\_intern(“new”), 0, rb\_yield(self));  
}

static VALUE kernel\_foo(VALUE self){  
VALUE v\_proc = rb\_proc\_new(foo\_block, self); /\* Also tried Qnil \*/  
return rb\_funcall(rb\_cObject, rb\_intern(“instance\_eval”), 0,  
v\_proc);  
}

rb\_define\_method(rb\_mKernel, “my\_meth”, kernel\_foo, 0);

But this doesn’t seem to work. When I try I do call my\_meth{  
“some\_string” } I  
get `instance\_eval’: block not supplied (ArgumentError)

What am I doing wrong here?

Thanks,

Dan

This communication is the property of Qwest and may contain confidential  
or  
privileged information. Unauthorized use of this communication is  
strictly  
prohibited and may be unlawful. If you have received this communication  
in error, please immediately notify the sender by reply e-mail and  
destroy  
all copies of the communication and any attachments.

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [August 28, 2006, 8:58pm UTC](https://www.ruby-forum.com/t/instance-eval-yield-c-extensions/66718/2 "2006-08-28T20:58:11Z")

</div>

Daniel B. [2006-08-29 01:41]:

Hi Daniel,  
I never worked with blocks in a C extension like you do, but I noticed a  
general problem in your code:

> static VALUE foo\_block(VALUE self){  
> return rb\_funcall(cFoo, rb\_intern(“new”), 0, rb\_yield(self));  
> ^  
> You’re passing one argument (the result of rb\_yield()), yet you tell  
> ruby to expect zero arguments. So make that 0 a 1.

> static VALUE kernel\_foo(VALUE self){  
> VALUE v\_proc = rb\_proc\_new(foo\_block, self); /\* Also tried Qnil \*/  
> return rb\_funcall(rb\_cObject, rb\_intern(“instance\_eval”), 0, v\_proc);

Some problem here.

HTH,  
Tilman

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [August 28, 2006, 9:40pm UTC](https://www.ruby-forum.com/t/instance-eval-yield-c-extensions/66718/3 "2006-08-28T21:40:19Z")

</div>

Tilman S. wrote:

> ruby to expect zero arguments. So make that 0 a 1.
> 
> > static VALUE kernel\_foo(VALUE self){  
> > VALUE v\_proc = rb\_proc\_new(foo\_block, self); /\* Also tried Qnil \*/  
> > return rb\_funcall(rb\_cObject, rb\_intern(“instance\_eval”), 0, v\_proc);
> 
> Some problem here.
> 
> HTH,  
> Tilman

Ok, fixing that I get “can’t convert Proc into String (TypeError)”.

Maybe I’m supposed to be using rb\_block\_proc, but I’m not entirely  
certain how  
it works.

Thanks,

Dan

This communication is the property of Qwest and may contain confidential  
or  
privileged information. Unauthorized use of this communication is  
strictly  
prohibited and may be unlawful. If you have received this communication  
in error, please immediately notify the sender by reply e-mail and  
destroy  
all copies of the communication and any attachments.

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [August 28, 2006, 9:50pm UTC](https://www.ruby-forum.com/t/instance-eval-yield-c-extensions/66718/4 "2006-08-28T21:50:21Z")

</div>

Daniel B. wrote:

> > You’re passing one argument (the result of rb\_yield()), yet you tell  
> > Tilman
> 
> Ok, fixing that I get “can’t convert Proc into String (TypeError)”.
> 
> Maybe I’m supposed to be using rb\_block\_proc, but I’m not entirely  
> certain how it works.
> 
> Thanks,
> 
> Dan

I guess I was over thinking it. This function works by itself:

static VALUE kernel\_foo(VALUE self){  
return rb\_funcall(cFoo, rb\_intern(“new”), 1,  
rb\_yield(rb\_block\_proc()));  
}

Regards,

Dan

This communication is the property of Qwest and may contain confidential  
or  
privileged information. Unauthorized use of this communication is  
strictly  
prohibited and may be unlawful. If you have received this communication  
in error, please immediately notify the sender by reply e-mail and  
destroy  
all copies of the communication and any attachments.

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [August 28, 2006, 9:52pm UTC](https://www.ruby-forum.com/t/instance-eval-yield-c-extensions/66718/5 "2006-08-28T21:52:44Z")

</div>

Daniel B. wrote:

> Tilman S. wrote:
> 
> > ruby to expect zero arguments. So make that 0 a 1.
> > 
> > > static VALUE kernel\_foo(VALUE self){  
> > > VALUE v\_proc = rb\_proc\_new(foo\_block, self); /\* Also tried Qnil \*/  
> > > return rb\_funcall(rb\_cObject, rb\_intern(“instance\_eval”), 0, v\_proc);
> > 
> > Some problem here.
> > 
> > HTH,  
> > Tilman
> 
> Ok, fixing that I get “can’t convert Proc into String (TypeError)”.

Right now that code is equivalent to

obj.instance\_eval block

Where it should be

obj.instance\_eval &block  
obj.instance\_eval {some\_code}  
obj.instance\_eval ‘some\_code’

> Maybe I’m supposed to be using rb\_block\_proc, but I’m not entirely  
> certain how  
> it works.
> 
> Thanks,
> 
> Dan

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [August 29, 2006, 5:07pm UTC](https://www.ruby-forum.com/t/instance-eval-yield-c-extensions/66718/6 "2006-08-29T17:07:29Z")

</div>

> > > > > “D” == Daniel B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

D\> static VALUE kernel\_foo(VALUE self){  
D\> return rb\_funcall(cFoo, rb\_intern(“new”), 1,  
rb\_yield(rb\_block\_proc()));  
^^^^^^^^^^^^^^^

You are giving the proc to the block, you have writing something like  
thid

def xxx(&block)  
Foo.new(yield(block))  
end

–

Guy Decoux
