getting a method from a block in C

E

elathan

Hello!

Suppose I have some ruby code:

def bar
puts "Hello"
end

foo { bar }

Now, foo is part of a Ruby extension, but bar is user implemented.
The C implementation of foo can use rb_block_given_p() to identify if
it was called with a block. My question is: can I grab the bar method, save
its pointer somewhere and call it from other places in my code? I.e. is
there an option in the Ruby C API to parse/identify args in a given block?

I don't want to yield bar, just save it and call it later (foo is actually a C++
constructor, which takes as an argument a pointer to a user function).


Regards,
 
T

ts

e> I don't want to yield bar, just save it and call it later (foo is
e> actually a C++ constructor, which takes as an argument a pointer to a
e> user function).

if (rb_block_given_p()) {
proc = rb_block_proc();
}

when you want to call it

rb_funcall(proc, rb_intern("call"), ...);

don't forget to define a mark function, and call rb_gc_mark(proc)


p.s. : for 1.6 this is rb_f_lambda() but this function is deprecated in 1.8


Guy Decoux
 
E

elathan

Quoting ts said:
if (rb_block_given_p()) {
proc = rb_block_proc();
}

when you want to call it

rb_funcall(proc, rb_intern("call"), ...);

Ah nice! That is what I wanted. Thanks a lot.
don't forget to define a mark function, and call rb_gc_mark(proc)

You mean a mark function for the Ruby garbage collector?

Regards,
--
 
T

ts

e> You mean a mark function for the Ruby garbage collector?

yes, the block must be marked otherwise the ruby GC will remove it.

This mean that you must define a mark function for your C++ object and
call rb_gc_mark(proc) inside it.


Guy Decoux
 
E

Elias Athanasopoulos

Hello Guy!

e> You mean a mark function for the Ruby garbage collector?

yes, the block must be marked otherwise the ruby GC will remove it.

This mean that you must define a mark function for your C++ object and
call rb_gc_mark(proc) inside it.

I think I have done what you suggested. However I get:

foo.rb:42: [BUG] rb_gc_mark(): unknown data type 0x28(0x89963f8) non object
ruby 1.8.0 (2003-08-04) [i586-linux]

Which means that I haven't done it in the right way.

I tried using gdb to identify the 'non-object' variable which can't be
marked, with no luck. Is there another way to accomplish this?

Also, the only way to associate a mark function with a new ruby class
is via Data_Wrap_Struct/Data_Make_Struct. Is this correct?

Regards,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top