Extension - redirect a block

hello,

I’v wrote an extension for a dll and at last I have to
implement a callback function.

My code.
— 8< —
def Callback_fn( var )
print "\7"
print " **************************** callback [#{var}] *** \n\r"
end

rv = RubyVSCL.new
rv.rPAInit { |a| Callback_fn(a) }
[…]
— 8< —

In my C-Function for rPAInit I check if rb_block_given_p and
call rb_yield - this works fine.

But in my thread which is listen on com1´´, rb_block_given_p says that no block is given. How toredirect´´ the block in the init function?

greetings,
daniel

But in my thread which is listen on ``com1´´, rb_block_given_p
says that no block is given.
How to ``redirect´´ the block in the init function?

Well I've not understood : do you want to do something like this ?

   class RubyVSCL
      def rPAInit
         @block = Proc.new
      end

      def on_event(a)
         @block[a]
      end
   end

Guy Decoux

“ts” decoux@moulon.inra.fr wrote in message
news:200304171134.h3HBY5r29784@moulon.inra.fr

But in my thread which is listen on com1´´, rb_block_given_p says that no block is given. How to redirect´´ the block in the init function?

Well I’ve not understood : do you want to do something like this ?
[…]

Not really…

In Ruby I call
rv.rPAInit { |a| Callback_fn(a) }

and use this block in my c-routines (in my dll).
And I need the block in another function!

In my wrapping-init function (in the dll, c-code)
the block is there and rb_yield does the right things.

But in another function (my thread)
rb_block_given_p
says there is no block and so I can’t do rb_yield.
But I need the block in the thread…

I’v tried some things like the example in the ruby-html-docu
(the CD-Player…) but rb_block_given_p fails (in my thread).

Also:
In the c-function which wrapped rPAInit the block is there.
In my thread the block is not there - but I need the the block
in my thread. I don’t know how to redirect the block…
It’s all c-code

daniel

“ts” decoux@moulon.inra.fr wrote in message news:200304171320.h3HDKGZ01634@moulon.inra.fr

  • only rPAInit is a ruby method, the second function is just a C method
    called. In this case you use a thread local variable.

hm…

This looks good.

rPAInit is a wrapping-c-method I called in ruby.

rPAInit() store the block (rb_thread_local_aset()) and the second
function retrieve it (rb_thread_local_aref()) and call it

are this functions documented?
There are some (bad) code-snippets in the internet.

your solution looks fine, thx

daniel

are this functions documented?
documented in eval.c

hm…

there is a global hash-table and I can
set a var and reference a var with
rb_thread_local_aref and rb_thread_local_aset.

But in the examples there is only ``__inspect_key__´´ -

I don’t know how to use this for my implementation…

daniel

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com wrote in message news:pan.2003.04.17.16.20.32.522456@sneakemail.com

···

On Thu, 17 Apr 2003 10:12:15 +0000, daniel wrote:

[…]

If you want to use Hash for keeping track of your global
instances, then have a look at VIM or Mod_ruby (both
uses hashes for this).

modruby.net
download : vim online

[…]

I already know how to use a hash and such things
for my interests. But in the example i mean how
to get the block (with ruby_intern?).

I’m going to browse through the ruby-sources…

daniel

“ts” decoux@moulon.inra.fr wrote in message news:200304171633.h3HGXYT04772@moulon.inra.fr

[…]

rb_thread_local_aset(rb_thread_current(), rb_intern(“block”), rb_f_lambda());

Then when the second function is called, you retrieve the block and call
it, something like

VALUE block, res;

block = rb_thread_local_aref(rb_thread_current(), rb_intern(“block”));
res = rb_funcall(block, rb_intern(“call”), 1, INT2FIX(12));

[…]

uh, this works!
however, I’ll check the appropriate part of the ruby-source to
understand this.

thx,
daniel

and use this block in my c-routines (in my dll).
And I need the block in another function!

Well there are 2 possibilities

  * the 2 functions are ruby method : in this case, this is just my
    previous example. You store the block in an instance variable when
    rPAInit is called and then call it in the second method

  * only rPAInit is a ruby method, the second function is just a C method
    called. In this case you use a thread local variable.
    rPAInit() store the block (rb_thread_local_aset()) and the second
    function retrieve it (rb_thread_local_aref()) and call it

Guy Decoux

are this functions documented?

documented in eval.c

There are some (bad) code-snippets in the internet.

You have an example in array.c

Guy Decoux

If you want to use Hash for keeping track of your global
instances, then have a look at VIM or Mod_ruby (both
uses hashes for this).

http://modruby.net/#label%3A11
http://www.vim.org/download.php

···

On Thu, 17 Apr 2003 10:12:15 +0000, daniel wrote:

are this functions documented?
documented in eval.c

hm…

there is a global hash-table and I can
set a var and reference a var with
rb_thread_local_aref and rb_thread_local_aset.

But in the examples there is only ``__inspect_key__´´ -

I don’t know how to use this for my implementation…


Simon Strandgaard

But in the examples there is only ``__inspect_key__´´ -
I don't know how to use this for my implementation...

Well, you can look in bdb (common.c) and plruby but they are really badly
written and perhaps only me can understand what they do :slight_smile:

Basically, in rPAInit() you store the block in a thread local variable,
something like

rb_thread_local_aset(rb_thread_current(), rb_intern("__block__"), rb_f_lambda());

Then when the second function is called, you retrieve the block and call
it, something like

VALUE block, res;

block = rb_thread_local_aref(rb_thread_current(), rb_intern("_block_"));
res = rb_funcall(block, rb_intern("call"), 1, INT2FIX(12));

Guy Decoux