Tutorial on embedding ruby (review)

What do you think about it ?

http://metaeditor.sourceforge.net/embed/

Critisism wanted !

  • point out where there is wrong usage of english ?
  • how do I make it more intuitive ?
  • other comments :slight_smile:

Last time I asked (10 days ago) it wasn’t much of a text, but
it has improved…

Thanks in advance
Simon Strandgaard

Simon Strandgaard wrote:

What do you think about it?

ruby embedded into c++

Critisism wanted !

  • point out where there is wrong usage of english ?
  • how do I make it more intuitive ?
  • other comments :slight_smile:

Last time I asked (10 days ago) it wasn’t much of a text, but
it has improved…

Simon, I have not had a chance to look over it yet, but I don’t want you
to think that the work is unappreciated :wink:

I am sure that this is going to be a valuable tutorial for anyone trying
to embed Ruby into some other application!

ruby embedded into c++
Figure 3 alone is one reason to look at it.
http://metaeditor.sourceforge.net/embed/cleanup.png

I printed it out. Will read the tutorial in a quiet hour.

In article 200304092336.07600.armin@xss.de,

¡¡¡

Armin Roehrl armin@xss.de wrote:

ruby embedded into c++
Figure 3 alone is one reason to look at it.
http://metaeditor.sourceforge.net/embed/cleanup.png

Figure 4 is pretty cool too.

I’m going to have to take a look at this part:
"Most people think that SWIG can be used ONLY for ruby extensions. But if
you are clever you can actual use it for embedding. "

Phil

ptkwt@shell1.aracnet.com (Phil Tomson) wrote in message news:b7251v087t@enews3.newsguy.com…

In article 200304092336.07600.armin@xss.de,

ruby embedded into c++
Figure 3 alone is one reason to look at it.
http://metaeditor.sourceforge.net/embed/cleanup.png

Figure 4 is pretty cool too.

I’m going to have to take a look at this part:
"Most people think that SWIG can be used ONLY for ruby extensions. But if
you are clever you can actual use it for embedding. "

Phil

Hi Simon,

I’m in the middle of embedding ruby into a c++ project and read the
tutorial with interest. It’s great to see something out there that
addresses this issue. I’ve already emailed you with some specific
questions but forgot to add commenst for the tutorial.I’m a newcomer
to ruby and swig so any info is great to see
So some points that I would find usefull would be:

  1. A more detailed explanation of THE GC interaction would be good. I’
    not sure if you need to do both marking and rb_global_variable and/or
    rb_gc_register_address. If I call rb_ary_new2 in my C code should I
    always inform the GC? I understand that I need to use a mark function
    for wrapped c classes but where do I get the VALUE from to pass to the
    mark function?
    If I am marking and object correctly what do I do when I want to free
    it off - just stop marking? The example given under ‘speed issues’
    protects the object list (using rb_gc_register_address) but what do I
    do if I want to free of just some of the objects in the list?. Also,
    what happend if the GC runs between objects = rb_ary_new() and
    rb_gc_register_address(&objects); ? Or can this never happen.

  2. An example explaining finializers would be nice - still not sure if
    I need them. Since I’m probably what Matz would describe as a ‘normal’
    user perhaps I should stear clear!.

  3. rb_require over rb_load_protect - I started off using rb_require
    but then found that if rb_require fails with a script error and I then
    corrected the script re re-rb_requiring ignored the changes - I assume
    the script is cached. Switching to rb_load_protect reloads the script
    each time - but is this correct? What does the second argument to
    rb_load_protect do

  4. More detail for the swig version - especially for the case when a
    ruby class inherits a swigged up c class and you need to pass a
    swigged up c class instance throug to it and then back out again

e.g.
c++:

SwigClass1 *sg = new SwigClass1();
sgValue = Data_Wrap_Struct(rb_path2class(“MyModule::SwigClass1”),0,0,(void
*)sg);

oClass = rb_const_get(rb_cObject, rb_intern(“SwigClass2”));
oObj = rb_funcall(oClass, rb_intern(“new”), 1,sgValue);

ruby:

class MyClass < MyModule::SwigClass2
def initialize(swigClassValue)
super(swigClassValue)
end
end

  1. Also under speed issues - should’nt void mystruct_alloc(VALUE
    klass) return VALUE?

All this is, of course, relevant to me at the moment and I don’t
expect answers (well, some would be nice) but I hope it helps. I’m new
to newsgroups too so I don’t even know what all the arreviations and
smiley colons mean yet!
Cheers
Steve

¡¡¡

Armin Roehrl armin@xss.de wrote:

It could happen but Ruby’s GC is conservative, which means that it will
scan the stack (where the variable objects lives) to find references to
objects. matz took care of it for you :slight_smile:

¡¡¡

On Thu, Apr 10, 2003 at 11:42:27AM +0900, Steve Hart wrote:

what happend if the GC runs between objects = rb_ary_new() and
rb_gc_register_address(&objects); ? Or can this never happen.

–
_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Never trust an operating system you don’t have sources for. :wink:
– Unknown source

I’m in the middle of embedding ruby into a c++ project and read the
tutorial with interest. It’s great to see something out there that
addresses this issue.

You are lucky that you don’t have to figure this out all over again :slight_smile:
You are doing very well… It has taken me too long time to get into
things, just to find out that they were all wrong (some of them).

  1. A more detailed explanation of THE GC interaction would be good. I’
    [snip gc issues/questions]

Many good questions…

  1. An example explaining finializers would be nice - still not sure if
    I need them. Since I’m probably what Matz would describe as a ‘normal’
    user perhaps I should stear clear!.

Maybe I should make it more clear, that I will not talk about
finalizers. And that you instead should use “close” + blocks.

  1. rb_require over rb_load_protect - I started off using rb_require
    but then found that if rb_require fails with a script error and I then
    corrected the script re re-rb_requiring ignored the changes - I assume
    the script is cached. Switching to rb_load_protect reloads the script
    each time - but is this correct?

Yes, thats correct.

What does the second argument to rb_load_protect do?

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=200104011037.f31AbrS21498%40orsay1.moulon.inra.fr&rnum=12&prev=/groups%3Fq%3Drb_load_protect%26hl%3Den%26lr%3D%26ie%3DUTF-8%26start%3D10%26sa%3DN
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=200302281436.h1SEaZT27859%40moulon.inra.fr

The reason why I am using rb_require is that I don’t
needs to re-load scripts… I just load them during
initialization, once and for all.

This is of cause something which must be explained in the text :slight_smile:

  1. More detail for the swig version - especially for the case when a
    ruby class inherits a swigged up c class and you need to pass a
    swigged up c class instance throug to it and then back out again
    [snip good example]

Yes. SWIG puts your classes under a “%module”-namespace. This makes
it a bit ackward… I wonder if its possible to avoid this namespace ?
Well something clearly must be written about this issue.

  1. Also under speed issues - should’nt void mystruct_alloc(VALUE
    klass) return VALUE?

Oops… yes.

Thanks for your efforts… this is just what I need.
Simon Strandgaard

¡¡¡

On Wed, 09 Apr 2003 20:35:03 +0000, Steve Hart wrote:

Please read:

Tobias

¡¡¡

On 9 Apr 2003, Steve Hart wrote:

  1. A more detailed explanation of THE GC interaction would be good. I’
    not sure if you need to do both marking and rb_global_variable and/or
    rb_gc_register_address. If I call rb_ary_new2 in my C code should I
    always inform the GC? I understand that I need to use a mark function
    for wrapped c classes but where do I get the VALUE from to pass to the
    mark function?
    If I am marking and object correctly what do I do when I want to free
    it off - just stop marking?

I have added your comments into the document, now I
just needs to answer them :slight_smile:

See revision 1.55
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/metaeditor/experiments/cpp_embed_ruby/embed.xml

Simon Strandgaard

Mauricio Fernández batsman.geo@yahoo.com wrote in message news:20030410075956.GA25804@student.ei.uni-stuttgart.de…

what happend if the GC runs between objects = rb_ary_new() and
rb_gc_register_address(&objects); ? Or can this never happen.

It could happen but Ruby’s GC is conservative, which means that it will
scan the stack (where the variable objects lives) to find references to
objects. matz took care of it for you :slight_smile:

–
_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Never trust an operating system you don’t have sources for. :wink:
– Unknown source

Yes, I’ve learnt a lot in the last 12 hours! I read some of the
threads relating to GC and think I have a better understanding now. If
the variable sits in the stack frame GC will pick it up automatically

  • great until it goes out of scope or, as in my case, get overwritten
    with another value (oops!). If the VALUE is stored elsewhere (C++
    class, struct etc) then you need to let GC know via register/mark.
    Still, it took me nearly 2 days to elicit this info from this news
    group which maybe proves the point regarding a decent guide which
    could explain these subtleties (and I could still have got it wrong!)
¡¡¡

On Thu, Apr 10, 2003 at 11:42:27AM +0900, Steve Hart wrote:

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

I’m in the middle of embedding ruby into a c++ project and read the
tutorial with interest. It’s great to see something out there that
addresses this issue.

You are lucky that you don’t have to figure this out all over again :slight_smile:
You are doing very well… It has taken me too long time to get into
things, just to find out that they were all wrong (some of them).

  1. A more detailed explanation of THE GC interaction would be good. I’
    [snip gc issues/questions]

Many good questions…

  1. An example explaining finializers would be nice - still not sure if
    I need them. Since I’m probably what Matz would describe as a ‘normal’
    user perhaps I should stear clear!.

Maybe I should make it more clear, that I will not talk about
finalizers. And that you instead should use “close” + blocks.

  1. rb_require over rb_load_protect - I started off using rb_require
    but then found that if rb_require fails with a script error and I then
    corrected the script re re-rb_requiring ignored the changes - I assume
    the script is cached. Switching to rb_load_protect reloads the script
    each time - but is this correct?

Yes, thats correct.

What does the second argument to rb_load_protect do?

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=200104011037.f31AbrS21498%40orsay1.moulon.inra.fr&rnum=12&prev=/groups%3Fq%3Drb_load_protect%26hl%3Den%26lr%3D%26ie%3DUTF-8%26start%3D10%26sa%3DN
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=200302281436.h1SEaZT27859%40moulon.inra.fr

The reason why I am using rb_require is that I don’t
needs to re-load scripts… I just load them during
initialization, once and for all.

This is of cause something which must be explained in the text :slight_smile:

  1. More detail for the swig version - especially for the case when a
    ruby class inherits a swigged up c class and you need to pass a
    swigged up c class instance throug to it and then back out again
    [snip good example]

Yes. SWIG puts your classes under a “%module”-namespace. This makes
it a bit ackward… I wonder if its possible to avoid this namespace ?
Well something clearly must be written about this issue.

  1. Also under speed issues - should’nt void mystruct_alloc(VALUE
    klass) return VALUE?

Oops… yes.

Thanks for your efforts… this is just what I need.
Simon Strandgaard

Thanks Simon,
Am looking at latest (1.65) now. I too, saw the aforementioned links
relating to rb_load(_protect) The question I meant to ask is realy
'What happens if I call rb_load twice with the same script? I guess
I’ll find out soon enough since I need to be able to do this. I’m also
still a bit unclear about ‘anonymous module’ - if it’s anonymous how
do you reference it?. All I know is that if I pass in 1 my call
crashes with uninitialized ‘constant (NameError)’
Anyway, keep up the great work - I for one am finding it invaluable.
Cheers

¡¡¡

On Wed, 09 Apr 2003 20:35:03 +0000, Steve Hart wrote:

Tobias Peters tpeters@invalid.uni-oldenburg.de wrote in message news:Pine.LNX.4.44.0304101407250.13250-100000@localhost.localdomain…

  1. A more detailed explanation of THE GC interaction would be good. I’
    not sure if you need to do both marking and rb_global_variable and/or
    rb_gc_register_address. If I call rb_ary_new2 in my C code should I
    always inform the GC? I understand that I need to use a mark function
    for wrapped c classes but where do I get the VALUE from to pass to the
    mark function?
    If I am marking and object correctly what do I do when I want to free
    it off - just stop marking?

Please read:

http://www.rubygarden.org/ruby?GCAndExtensions

Tobias

I did. It was useful as far as it went. What it did’nt say was how the
object created with Data_Wrap_Struct could be registered with the GC.
Neither did it mention how the interpreter marks the current stack
frame when ruby_init() is called thus enabling c side ruby objects to
be automatically marked by the GC. Knowing this then raises the
question of how to tell the GC that, if the previously created object
is retained (struct,heap etc), it should not be reaped
Finally, it does not explain how to release a retained object when
you’re done.
Perhaps Simon could extend this into his tutorial.

¡¡¡

On 9 Apr 2003, Steve Hart wrote:

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

¡¡¡

On Wed, 09 Apr 2003 20:35:03 +0000, Steve Hart wrote:

I’m in the middle of embedding ruby into a c++ project and read the
tutorial with interest. It’s great to see something out there that
addresses this issue.

You are lucky that you don’t have to figure this out all over again :slight_smile:
You are doing very well… It has taken me too long time to get into
things, just to find out that they were all wrong (some of them).

  1. A more detailed explanation of THE GC interaction would be good. I’
    [snip gc issues/questions]

Many good questions…

  1. An example explaining finializers would be nice - still not sure if
    I need them. Since I’m probably what Matz would describe as a ‘normal’
    user perhaps I should stear clear!.

Maybe I should make it more clear, that I will not talk about
finalizers. And that you instead should use “close” + blocks.

  1. rb_require over rb_load_protect - I started off using rb_require
    but then found that if rb_require fails with a script error and I then
    corrected the script re re-rb_requiring ignored the changes - I assume
    the script is cached. Switching to rb_load_protect reloads the script
    each time - but is this correct?

Yes, thats correct.

What does the second argument to rb_load_protect do?

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=200104011037.f31AbrS21498%40orsay1.moulon.inra.fr&rnum=12&prev=/groups%3Fq%3Drb_load_protect%26hl%3Den%26lr%3D%26ie%3DUTF-8%26start%3D10%26sa%3DN
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=200302281436.h1SEaZT27859%40moulon.inra.fr

The reason why I am using rb_require is that I don’t
needs to re-load scripts… I just load them during
initialization, once and for all.

This is of cause something which must be explained in the text :slight_smile:

  1. More detail for the swig version - especially for the case when a
    ruby class inherits a swigged up c class and you need to pass a
    swigged up c class instance throug to it and then back out again
    [snip good example]

Yes. SWIG puts your classes under a “%module”-namespace. This makes
it a bit ackward… I wonder if its possible to avoid this namespace ?
Well something clearly must be written about this issue.

  1. Also under speed issues - should’nt void mystruct_alloc(VALUE
    klass) return VALUE?

Oops… yes.

Thanks for your efforts… this is just what I need.
Simon Strandgaard

Hi Simon,
I hope this does not remove my last post
I had a problem compliling the tutorial code - it fails looking to libdl
Easy to fix or prob at my end?
Cheers

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

¡¡¡

On Wed, 09 Apr 2003 20:35:03 +0000, Steve Hart wrote:

I’m in the middle of embedding ruby into a c++ project and read the
tutorial with interest. It’s great to see something out there that
addresses this issue.

You are lucky that you don’t have to figure this out all over again :slight_smile:
You are doing very well… It has taken me too long time to get into
things, just to find out that they were all wrong (some of them).

  1. A more detailed explanation of THE GC interaction would be good. I’
    [snip gc issues/questions]

Many good questions…

  1. An example explaining finializers would be nice - still not sure if
    I need them. Since I’m probably what Matz would describe as a ‘normal’
    user perhaps I should stear clear!.

Maybe I should make it more clear, that I will not talk about
finalizers. And that you instead should use “close” + blocks.

  1. rb_require over rb_load_protect - I started off using rb_require
    but then found that if rb_require fails with a script error and I then
    corrected the script re re-rb_requiring ignored the changes - I assume
    the script is cached. Switching to rb_load_protect reloads the script
    each time - but is this correct?

Yes, thats correct.

What does the second argument to rb_load_protect do?

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=200104011037.f31AbrS21498%40orsay1.moulon.inra.fr&rnum=12&prev=/groups%3Fq%3Drb_load_protect%26hl%3Den%26lr%3D%26ie%3DUTF-8%26start%3D10%26sa%3DN
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=200302281436.h1SEaZT27859%40moulon.inra.fr

The reason why I am using rb_require is that I don’t
needs to re-load scripts… I just load them during
initialization, once and for all.

This is of cause something which must be explained in the text :slight_smile:

  1. More detail for the swig version - especially for the case when a
    ruby class inherits a swigged up c class and you need to pass a
    swigged up c class instance throug to it and then back out again
    [snip good example]

Yes. SWIG puts your classes under a “%module”-namespace. This makes
it a bit ackward… I wonder if its possible to avoid this namespace ?
Well something clearly must be written about this issue.

  1. Also under speed issues - should’nt void mystruct_alloc(VALUE
    klass) return VALUE?

Oops… yes.

Thanks for your efforts… this is just what I need.
Simon Strandgaard

One other thing on the tutorial,
It may be worth noting that you can compile the swig wrapper up into a
…so which you can either require from your script or rb_require from
your cpp code after the ruby_init()

'What happens if I call rb_load twice with the same script?

rb_require() versus rb_load()… what is the difference ?
OK… here is some pseudo code

def rb_require(name)
# load the file one time (maximum)
if not already loaded
load(name)
end

rb_require = think of a load_once

rb_load() can load a file several times.

I’m also still a bit unclear about ‘anonymous module’ - if it’s
anonymous how do you reference it?.

Sorry Im only familier with rb_require… I know absolutely
nothing about rb_load :slight_smile:

All I know is that if I pass in 1 my call
crashes with uninitialized ‘constant (NameError)’

How does you full backtrace look like ?

Anyway, keep up the great work - I for one am finding it invaluable.

I have only recieved suggestions/comments from you…(I did’nt thought it
would be that hard to get it reviewed, maybe I will come automaticly :slight_smile:

Im very grateful that you have taken your time to read it and
challenge me :slight_smile:

Thanks again
Simon Strandgaard

¡¡¡

On Sun, 13 Apr 2003 19:42:01 +0000, Steve Hart wrote:

I hope this does not remove my last post

Which newsreader are you using ?
I can recommend “pan”, its lightweight and doesn’t segfault.

I had a problem compliling the tutorial code - it fails looking to libdl
Easy to fix or prob at my end?

From previous posts I know that you are running linux… My own system
is freebsd5. This difference is probably the problem.

This is a autoconf/automake issue… I better browse google to get more
info about this. Then I will get back :slight_smile:

Unfortunatly I don’t have a linux system which I can test it on.
Maybe some other ruby-fellow with autoconf experience can help
getting this to compile on linux ???

http://metaeditor.sourceforge.net/embed/rubyembed-0.1.tar.gz
http://metaeditor.sourceforge.net/embed/

Is there any linux/autoconf experts around ???

¡¡¡

On Sun, 13 Apr 2003 20:35:26 +0000, Steve Hart wrote:

–
Simon Strandgaard

I'll find out soon enough since I need to be able to do this. I'm also
still a bit unclear about 'anonymous module' - if it's anonymous how
do you reference it?. All I know is that if I pass in 1 my call
crashes with uninitialized 'constant <classname> (NameError)'

You don't reference it : one use is when you don't want the the loaded
file 'pollute' your classes. A small example to see the difference

pigeon% cat c.rb
#!/usr/bin/ruby
class A
   def a
      p "c.rb : b"
   end
end

A.new.a

pigeon%

pigeon% cat b.rb
#!/usr/bin/ruby
class A
   def a
      p "b.rb : a"
   end
end

load 'c.rb', true
A.new.a
load 'c.rb'
A.new.a

pigeon%

pigeon% b.rb
"c.rb : b"
"b.rb : a"
"c.rb : b"
"c.rb : b"
pigeon%

Guy Decoux

http://www.rubygarden.org/ruby?GCAndExtensions
I did. It was useful as far as it went. What it did’nt say was how the
object created with Data_Wrap_Struct could be registered with the GC.

Thanks for the critique. I don’t want to look it up in “Programming Ruby”
right now, but basically, Data_Wrap_Struct takes two functions as
argument (besides the Struct in question), and creates a new ruby object.

The new ruby object is automatically known to the Garbage collector. You
don’t have to do anything else to “register” it.

But you can register two functions for your new object that will be called
from the garbage collector. This reqistration is part of
Data_Wrap_Struct’s action. Pass pointers to these functions as arguments
of the Data_Wrap_Struct macro.

These two function arguments take function pointers to be called during
the mark phase and the sweep phase of the GC, respectively. The latter
will only be called if the object is finally deleted.

Neither did it mention how the interpreter marks the current stack
frame when ruby_init()

I’m no expert here, but I don’t think it marks the current stack frame,
because there is no need to do this. The GC can simply scan the whole C
stack for pointers to ruby objects.

is called thus enabling c side ruby objects to
be automatically marked by the GC.

If there are pointers to these Objects on the stack (variables of type
VALUE), then they will automatically be marked every time the GC enters a
mark phase.

Knowing this then raises the
question of how to tell the GC that, if the previously created object
is retained (struct,heap etc), it should not be reaped

I don’t understand this.

Finally, it does not explain how to release a retained object when
you’re done.

A ruby object is deleted after a GC mark phase, iff it did not recieve a
mark during that particular mark phase. You can not explicitly delete an
object. That’s the GC’s responsibility.

Tobias

¡¡¡

On 13 Apr 2003, Steve Hart wrote:

linux-slackware problems with libdl, see:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=01bc1682%24705e0260%24170f989e%40cdmack.demon.co.uk&rnum=9&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DISO-8859-1%26q%3Dwhat%2Bis%2Blibdl%2B

what is libdl ?
libdl.so is a dynamic linking library that is generally of use only for
porting applications. If you are porting a BeOS application that requires
dlopen, dlclose, dlerror, dlsym, dladdr, or dlfcn.h, then you can use this library.

libdl.so is a wrapper to the add-on functions with the semantics of the
dl (dynamic linking) library. This is used for finding shared objects at
run time. If the items are not found the program can continue to run.
(description ripped from bebits.com :slight_smile:

What linux distribution are you using ?

¡¡¡

On Mon, 14 Apr 2003 06:01:04 +0200, Simon Strandgaard wrote:

On Sun, 13 Apr 2003 20:35:26 +0000, Steve Hart wrote:

I had a problem compliling the tutorial code - it fails looking to libdl
Easy to fix or prob at my end?

From previous posts I know that you are running linux… My own system
is freebsd5. This difference is probably the problem.

–
Simon Strandgaard

Tobias Peters tpeters@invalid.uni-oldenburg.de wrote in message news:Pine.LNX.4.44.0304140936180.15336-100000@localhost.localdomain…

http://www.rubygarden.org/ruby?GCAndExtensions
I did. It was useful as far as it went. What it did’nt say was how the
object created with Data_Wrap_Struct could be registered with the GC.

Thanks for the critique. I don’t want to look it up in “Programming Ruby”
right now, but basically, Data_Wrap_Struct takes two functions as
argument (besides the Struct in question), and creates a new ruby object.

The new ruby object is automatically known to the Garbage collector. You
don’t have to do anything else to “register” it.

But you can register two functions for your new object that will be called
from the garbage collector. This reqistration is part of
Data_Wrap_Struct’s action. Pass pointers to these functions as arguments
of the Data_Wrap_Struct macro.

These two function arguments take function pointers to be called during
the mark phase and the sweep phase of the GC, respectively. The latter
will only be called if the object is finally deleted.

Neither did it mention how the interpreter marks the current stack
frame when ruby_init()

I’m no expert here, but I don’t think it marks the current stack frame,
because there is no need to do this. The GC can simply scan the whole C
stack for pointers to ruby objects.

is called thus enabling c side ruby objects to
be automatically marked by the GC.

If there are pointers to these Objects on the stack (variables of type
VALUE), then they will automatically be marked every time the GC enters a
mark phase.

Knowing this then raises the
question of how to tell the GC that, if the previously created object
is retained (struct,heap etc), it should not be reaped

I don’t understand this.

Finally, it does not explain how to release a retained object when
you’re done.

A ruby object is deleted after a GC mark phase, iff it did not recieve a
mark during that particular mark phase. You can not explicitly delete an
object. That’s the GC’s responsibility.

Tobias

Sorry, should have said it was very useful (as far as it went :-). My
point was that if you wrap an object using Data_Wrap_Struct the object
returned resides on the stack - fine. If the object goes out of scope
then GC deletes it. No?
The only way to prevent GC from deleting it would be to save the
object in some system allocated memory AND tell GC using either
rb_gc_register_address or rb_global_variable. rb_gc_register_address
has a complementary function rb_gc_unregister_address which removes
the object from GC’s safe list. rb_global_variable does not.

Anyway, my only point really was that the GCAndExtensions could be
expanded into the tutorial simon is writing. No criticism intended.I
would’nt be using Ruby/Swig if I did’nt think they were both pretty
damm fine pieces of software
Cheers

Cheers

¡¡¡

On 13 Apr 2003, Steve Hart wrote: