[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

instance_eval, yield, C extensions

Berger, Daniel

8/28/2006 4:41:00 PM

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.

5 Answers

Tilman Sauerbeck

8/28/2006 6:56:00 PM

0

Daniel Berger [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

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Berger, Daniel

8/28/2006 7:40:00 PM

0

Tilman Sauerbeck wrote:
> Daniel Berger [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

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.

Berger, Daniel

8/28/2006 7:49:00 PM

0

Daniel Berger wrote:
> Tilman Sauerbeck wrote:
>> Daniel Berger [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
>
> 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.

e

8/28/2006 7:53:00 PM

0

Daniel Berger wrote:
> Tilman Sauerbeck 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


--
Posted via http://www.ruby-....

ts

8/29/2006 2:57:00 PM

0

>>>>> "D" == Daniel Berger <Daniel.Berger@qwest.com> 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