Embedding 1.9

Folks:

I'm working on the "Extending Ruby" chapter (now an appendix) for the third PickAxe, and I'm finding a whole bunch of conflicting information. Reading the source, it seems like there's no canonical way of embedding Ruby in a C application. I have lots of alternatives that _seem_ to work, but I want to be more authoritative than that.

Does anyone have any pointers to stuff that would help?

Thanks

Dave

Have you checked out VIM? It has ruby embedded and provides an interface into vim buffers from ruby. HTH. Good luck.
  --mark

···

--
blog: http://hasno.info

Dave Thomas wrote:

Folks:

I'm working on the "Extending Ruby" chapter (now an appendix) for the third PickAxe, and I'm finding a whole bunch of conflicting information. Reading the source, it seems like there's no canonical way of embedding Ruby in a C application. I have lots of alternatives that _seem_ to work, but I want to be more authoritative than that.

Does anyone have any pointers to stuff that would help?

Thanks

Dave

Hi,

Folks:

I'm working on the "Extending Ruby" chapter (now an appendix) for the
third PickAxe, and I'm finding a whole bunch of conflicting
information. Reading the source, it seems like there's no canonical
way of embedding Ruby in a C application. I have lots of alternatives
that _seem_ to work, but I want to be more authoritative than that.

Does anyone have any pointers to stuff that would help?

Perhaps "authoritative" means "information from the original author"
but I don't remember I wrote such document (sigh).

Basically, you have to call:

  ruby_sysinit() for command line argument initialization (optional)
  RUBY_INIT_STACK() for GC stack initialization
  ruby_init() for ruby interpreter initialization

and wrap ruby calls with rb_protect() for initialize exception frame.
You can load Ruby programs with rb_load(). You can call ruby programs
from string via rb_eval_string().

              matz.

···

In message "Re: Embedding 1.9" on Tue, 8 Jan 2008 06:44:08 +0900, Dave Thomas <dave@pragprog.com> writes:

Mark:

I don;t believe it has Ruby 1.9, though.

Dave

···

On Jan 7, 2008, at 7:41 PM, Mark Guzman wrote:

Have you checked out VIM? It has ruby embedded and provides an interface into vim buffers from ruby. HTH. Good luck.

In 1.9, do we also now need to call set_locale()?

Dave

···

On Jan 7, 2008, at 9:36 PM, Yukihiro Matsumoto wrote:

Perhaps "authoritative" means "information from the original author"
but I don't remember I wrote such document (sigh).

Basically, you have to call:

ruby_sysinit() for command line argument initialization (optional)
RUBY_INIT_STACK() for GC stack initialization
ruby_init() for ruby interpreter initialization

and wrap ruby calls with rb_protect() for initialize exception frame.
You can load Ruby programs with rb_load(). You can call ruby programs
from string via rb_eval_string().

good day all,

while it's still hot talking about embedding, let me ask a related question
here: is there any way to do reflection from ruby C API?

rgds,
Edwin.

···

On Tuesday 08 January 2008 10:36:56 am Yukihiro Matsumoto wrote:

Basically, you have to call:

  ruby_sysinit() for command line argument initialization (optional)
  RUBY_INIT_STACK() for GC stack initialization
  ruby_init() for ruby interpreter initialization

and wrap ruby calls with rb_protect() for initialize exception frame.
You can load Ruby programs with rb_load(). You can call ruby programs
from string via rb_eval_string().

              matz.

Hi,

···

In message "Re: Embedding 1.9" on Tue, 8 Jan 2008 13:22:01 +0900, Dave Thomas <dave@pragprog.com> writes:

In 1.9, do we also now need to call set_locale()?

Do you mean setlocale()? It's optional. If you call it,
Encoding.default_external will be set according to your locale,
otherwise it will be ASCII-8BIT.

              matz.

Dave Thomas wrote:

Have you checked out VIM? It has ruby embedded and provides an interface into vim buffers from ruby. HTH. Good luck.

Mark:

I don;t believe it has Ruby 1.9, though.

Dave

Quite true. My addled eyes missed the blatant 1.9 in the title.

It did get me started on applying a little elbow work to them problem. The vim code ports to 1.9 just fine. Changing a few of those pesky RSTRING(xyz)->ptr and len's to their new macros eliminates the majority of the compile errors. The only other item seems to be error info handling, which went from being a static variable to a function rb_errinfo. I'm sure you've already run into all the nitty gritty. I've attached a patch versus the current
vim trunk. I haven't tried anything more intensive than loading and executing a simple file as of yet.

--mark

if_ruby_19.patch (3.26 KB)

···

On Jan 7, 2008, at 7:41 PM, Mark Guzman wrote:

Hi,

···

In message "Re: Embedding 1.9" on Wed, 9 Jan 2008 18:45:44 +0900, Edwin Pratomo <edwin@imt.co.id> writes:

while it's still hot talking about embedding, let me ask a related question
here: is there any way to do reflection from ruby C API?

What kind of reflection? You can define classes, inspect variables,
etc. from C.

              matz.

Mark:

Are you manually defining the TAG_xxx values somewhere? eval_intern.h isn't installed onto the user side on my box.

Dave

···

On Jan 8, 2008, at 12:20 AM, Mark Guzman wrote:

    case TAG_RAISE:
    case TAG_FATAL:

However, calling setlocale should not break ruby 1.9 since the
interpreter does it as well :wink:

Thanks

Michal

···

On 08/01/2008, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

Hi,

In message "Re: Embedding 1.9" > on Tue, 8 Jan 2008 13:22:01 +0900, Dave Thomas <dave@pragprog.com> writes:

>In 1.9, do we also now need to call set_locale()?

Do you mean setlocale()? It's optional. If you call it,
Encoding.default_external will be set according to your locale,
otherwise it will be ASCII-8BIT.

in particular, what I would like to do is Object.private_methods, in C way.

rgds,
Edwin.

···

--- Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

Hi,

In message "Re: Embedding 1.9" > on Wed, 9 Jan 2008 18:45:44 +0900, Edwin Pratomo <edwin@imt.co.id> > writes:

>while it's still hot talking about embedding, let me ask a related question
>here: is there any way to do reflection from ruby C API?

What kind of reflection? You can define classes, inspect variables,
etc. from C.

      ________________________________________________________
Bergabunglah dengan orang-orang yang berwawasan, di di bidang Anda! Kunjungi Yahoo! Answers saat ini juga di http://id.answers.yahoo.com/

Right. The interpreter calls a bunch of methods during initialization. I'm trying to determine the minimum subset required for safe 1.9 operation. I _think_ I've got it now, and I'll be pushing it as part of the beta in the next few days.

Thanks

Dave

···

On Jan 8, 2008, at 1:59 AM, Michal Suchanek wrote:

However, calling setlocale should not break ruby 1.9 since the
interpreter does it as well :wink:

<(08/01/08 16:08) Dave Thomas>

Are you manually defining the TAG_xxx values somewhere? eval_intern.h isn't
installed onto the user side on my box.

Dave,
Those are defined locally in if_ruby.c, that seems to be the convention
as the tcltk extension does the same. I wonder if those should be pushed
into ruby.h to ease embedding...?
  --mark

···

--
Those the gods wish to destroy they call promising.
blog: http://hasno.info

To call a method that's available in RUby, just use rb_funcall

    rb_funcall(receiver, mid, argc, arg, arg, ...)

The mid parameter is the ID of the method to invoke (nor its name) and the arguments (if any) are VALUEs,

Dave

···

On Jan 9, 2008, at 4:17 AM, Edwin Pratomo wrote:

in particular, what I would like to do is Object.private_methods, in C way.

That'd get my vote. I've copied core on this..

Dave

···

On Jan 8, 2008, at 11:05 AM, Mark Guzman wrote:

Are you manually defining the TAG_xxx values somewhere? eval_intern.h isn't
installed onto the user side on my box.

Dave,
Those are defined locally in if_ruby.c, that seems to be the convention
as the tcltk extension does the same. I wonder if those should be pushed
into ruby.h to ease embedding...?

thanks dave, for the pointer.

now I got the following code works (but there is some problem):

static VALUE eval_failed()
{
    printf("eval failed\n");
    return Qnil;
}
    
static VALUE my_each(VALUE obj)
{
    return rb_funcall(obj, rb_intern("each"), 0);
}

static VALUE my_iterator(VALUE obj)
{
    int error;
    VALUE result;

    result = rb_protect(my_each, obj, &error);
    return error ? Qnil : result;
}

static VALUE my_iterator_block(VALUE res)
{
    printf("args: %s\n", STR2CSTR(rb_inspect(res)));
    return Qnil;
}

int main(void) {
    char *silly = "def foo; end";

    ruby_init();
    ruby_init_loadpath();

    /* def foo */
    rb_rescue(rb_eval_string, (VALUE)silly, eval_failed, 0);

    /* Object.private_methods */
    {
        VALUE obj = rb_funcall(rb_cObject, rb_intern("private_methods"), 0);
        if (TYPE(obj) == T_ARRAY) {
            printf("Array!\n");
            /* obj.each {|v| pp v } */
            rb_iterate(
                my_iterator,
                obj,
                my_iterator_block,
                0
            );

        } else {
            printf("Not array! Can't proceed\n");
        }
    }

    ruby_finalize();
    exit(0);
}

__END__

but "foo" is not there! why is it different from:

def foo
end

Object.private_methods.each do |x|
  puts x
end

puts "===================="

Object.private_methods.select {|x| x =~ /foo/ }.each do |x|
  puts x
end

__END__

rgds,
Edwin.

···

--- Dave Thomas <dave@pragprog.com> wrote:

On Jan 9, 2008, at 4:17 AM, Edwin Pratomo wrote:

> in particular, what I would like to do is Object.private_methods, in
> C way.

To call a method that's available in RUby, just use rb_funcall

    rb_funcall(receiver, mid, argc, arg, arg, ...)

The mid parameter is the ID of the method to invoke (nor its name) and
the arguments (if any) are VALUEs,

      ________________________________________________________
Bergabunglah dengan orang-orang yang berwawasan, di di bidang Anda! Kunjungi Yahoo! Answers saat ini juga di http://id.answers.yahoo.com/

I submitted a bug for this a while ago:

http://rubyforge.org/tracker/?func=detail&atid=1698&aid=13838&group_id=426

I see no reason for this to be an opaque value.

Currently I use the #ifndef trick to get the TAG_ macros.

Paul

···

On Wed, Jan 09, 2008 at 03:03:49AM +0900, Dave Thomas wrote:

> Dave,
> Those are defined locally in if_ruby.c, that seems to be the
> convention as the tcltk extension does the same. I wonder if those
> should be pushed into ruby.h to ease embedding...?

That'd get my vote. I've copied core on this..