Latest info on embedding Ruby in a C++ app

I'm looking for info on calling multiple Ruby scripts from inside a C++
application. Is there anything like a definitive document about doing
this?

So far, I've googled the web and comp.lang.ruby, and I've looked at the
Pragmatic Guide.

As a test, I have:

int main(int argc, char** argv)
{
#ifdef WIN32
    NtInitialize(&argc, &argv);
#endif

    ruby_init();
    ruby_script("embedded");

    char* filename = 0;

    int status = 0;

    for (int i = 0; i < 3; ++i)
    {
        // [snip] do something to put the script path
        // into filename for this iteration.

// rb_load_protect(rb_str_new2(filename), 0, &status);
        rb_load_file(filename);

// if (status == 0)
// {
            // [snip] set command arguments
            // and call ruby_set_argv()

            status = ruby_exec();
// }
    }

    ruby_cleanup(status);

    return 0;
}

I know I need to wrap things in rb_protect() to save me from Ruby
crashing the whole application. Are there any gotchas here?

How do I get the value of Kernel::exit once a Ruby script finishes?
ruby_exec() seems to only return 0 or 6.

If I am executing multiple scripts, should I just call ruby_init() once
at the beginning and ruby_cleanup() once at the end?

Thanks,

-- Timothy

Timothy Byrd wrote:

I'm looking for info on calling multiple Ruby scripts from inside a C++
application. Is there anything like a definitive document about doing
this?

So far, I've googled the web and comp.lang.ruby, and I've looked at the
Pragmatic Guide.
[...]

You don't mention the wiki entry, so:

Hope that'll help.

daz

daz wrote:

You don't mention the wiki entry, so:
http://www.rubygarden.org/ruby?EmbedRuby

Thanks. I did look at that, and it gives some answers and raises some
more questions.

Now the pressing issue is how I can capture all the output of the Ruby
script. (Imagine a GUI-based command shell that needs to be able to
snag all the console IO of the Ruby script.) There are some initial
thoughts about this in the embedding tutorial at
ruby embedded into c++ .

Would it be possible to inject an overload for IO#write or somesuch
from the C program into Ruby before the script runs? If so, how could
I do that? Otherwise, I might have to make a special build of Ruby to
do callbacks into the app, and that's not nice.

-- Timothy

This method won't capture everything (e.g. if the script calls external
programs or uses other more devious means of writing to stdout/err), but
consider:

irb(main):001:0> require 'stringio'
=> true
irb(main):002:0> s = StringIO.new
=> #<StringIO:0x4031ac7c>
irb(main):003:0> $stderr = s
=> #<StringIO:0x4031ac7c>
irb(main):004:0> $stderr.puts "This is a test"
=> nil
irb(main):009:0> s.string
=> "This is a test\n"

Otherwise you must use a dup2 or a similar mechanism to redirect output to a
pipe or a socket.

Paul

···

On Fri, Sep 02, 2005 at 02:56:24AM +0900, Timothy Byrd wrote:

Now the pressing issue is how I can capture all the output of the Ruby
script.