Embedding 1.9

On Wed, Jan 09, 2008 at 02:04:03AM +0900, Dave T. wrote:

rb_eval_string("$result = $summer.sum(10)");
result = rb_gv_get(“result”);
printf(“Result = %d\n”, NUM2INT(result));
ruby_finalize();
exit(0);
}

Before I added sum.rb:

class Summer
def sum(*args)
args.inject { |sum, x| sum + x }
end
end

I was getting a segfault running your example:

[pbrannan@zaphod embed]$ ./embed
:17: [BUG] Segmentation fault
ruby 1.9.0 (2008-01-04 revision 0) [i686-linux]

Your example should catch exceptions:

VALUE embeded(VALUE ignore)
{
VALUE result;
rb_require(“sum.rb”);
rb_eval_string("$summer = Summer.new");
rb_eval_string("$result = $summer.sum(10)");
result = rb_gv_get(“result”);
printf(“Result = %d\n”, NUM2INT(result));
return Qnil;
}

int main(int argc, char **argv) {
int state;

ruby_sysinit(&argc, &argv);
RUBY_INIT_STACK;
ruby_init();
ruby_options(argc, argv);

rb_protect(embeded, Qnil, &state);
return ruby_cleanup(state);

}

to prevent the segfault:

[pbrannan@zaphod embed]$ mv sum.rb sum_bk.rb
[pbrannan@zaphod embed]$ ./embed
ruby 1.9.0 (2008-01-08 revision 0) [i686-linux]
:17: no such file to load – sum.rb (LoadError)

I also removed the call to exit(0) and replaced ruby_init_loadpath()
with ruby_options().

I think there’s still some work left to do, because:

  • the filename is wrong (“dummy toplevel”).
  • TOPLEVEL_BINDING is undefined
  • NameError exceptions aren’t getting caught (the program just exits)
  • I can’t require shared objects (rb_require(“socket”) gives an error
    about rb_eRuntimeError being undefined)

I don’t know which of these are bugs in my code and which are bugs in
the interpreter.

BTW, how are you determining which options to pass to the
compiler/linker? I
feel there should be a better way than what I’m doing:

ruby_config() { ruby1.9 -rrbconfig -e “puts Config::CONFIG[’$1’]” |
grep -v “ruby 1.9.0”; }
gcc embed.c -o embed
-I ruby_config rubyhdrdir
-I ruby_config rubyhdrdir/ruby_config arch
-L ruby_config libdir
ruby_config LDFLAGS
ruby_config LIBS
ruby_config LIBRUBYARG

I’m unsure whether I should be using LDFLAGS above, since it contains
the string “-L.”, which seems wrong.

Paul

On Jan 8, 2008, at 3:35 PM, Paul B. wrote:

I think there’s still some work left to do, because:

  • the filename is wrong (“dummy toplevel”).
  • TOPLEVEL_BINDING is undefined
  • NameError exceptions aren’t getting caught (the program just exits)
  • I can’t require shared objects (rb_require(“socket”) gives an error
    about rb_eRuntimeError being undefined)

I don’t know which of these are bugs in my code and which are bugs in
the interpreter.

Then there’s the gems initialization issue

Matz:

Is there a plan to provide an interface to initialize a Ruby
environment for embedding, or should I simply say that embedding Ruby
is not supported in 1.9, and to wait for 2.0?

Dave

Hi,

In message “Re: Embedding 1.9”
on Wed, 9 Jan 2008 07:25:42 +0900, Dave T. [email protected]
writes:

|Then there’s the gems initialization issue

I’m sorry but I am no gems expert, but basically gems should work if
you initialize the load path properly.

|Matz:
|
|Is there a plan to provide an interface to initialize a Ruby
|environment for embedding, or should I simply say that embedding Ruby
|is not supported in 1.9, and to wait for 2.0?

Embedding have not been the primary goal of the Ruby implementation.
But you can embed it with some restriction (only one interpreter per
process, no global reset, etc). The situation may be changed when
multiple VM system is introduced to YARV. I know Koichi is working
on it (among other tasks), but don’t know when.

          matz.

Hi,

At Wed, 9 Jan 2008 02:04:03 +0900,
Dave T. wrote in [ruby-core:14848]:

int main(int argc, char **argv) {
VALUE result;

ruby_sysinit(&argc, &argv);
RUBY_INIT_STACK;

RUBY_INIT_STACK must be at the top of a block, since it
contains a variable declaration.

And RUBY_GLOBAL_SETUP should be before main().

ruby_init();
ruby_init_loadpath();

rb_require(“sum.rb”);
rb_eval_string("$summer = Summer.new");
rb_eval_string("$result = $summer.sum(10)");
result = rb_gv_get(“result”);
“$result”

rb_gv_get and others need the sigil.

Dave T. wrote:

from code that embeds Ruby. It is called from process options, but
process options does too much.

What does process_options()/ruby_options() do that you don’t like? You
don’t have to pass it the real argc/argv.

Paul

On Jan 8, 2008, at 8:34 PM, Yukihiro M. wrote:

I’m sorry but I am no gems expert, but basically gems should work if
you initialize the load path properly.

I’m not sure how to call this method:

static void
ruby_init_gems(struct cmdline_options *opt)
{
VALUE gem;
gem = rb_define_module(“Gem”);
rb_const_set(gem, rb_intern(“Enable”), opt->disable_gems ?
Qfalse : Qtrue);
Init_prelude();
}

from code that embeds Ruby. It is called from process options, but
process options does too much.

Dave

On Jan 9, 2008, at 12:35 AM, Paul B. wrote:

What does process_options()/ruby_options() do that you don’t like?
You don’t have to pass it the real argc/argv.

It’ll still use RUBYOPT, and potentially change the encoding.

But, in truth, the problem really is that I’m struggling here with the
fact that there just isn’t a consensus from the people who know on
just how we embed Ruby 1.9. I think it’s perfectly reasonable that
during this period of transition the embedding protocol hasn’t been
worked out. I’d just like to confirm this, so I can produce something
that will help people when they read the book (even if that something
is “there’s no agreed-upon way to embed Ruby 1.9”).

I know it seems like I’m being awkward: I’m honestly not. I just want
to tell PickAxe readers how to do this correctly, and every way I’ve
tried in the last day or so has had some kind of problem associated
with it.

Dave

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

          matz.

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.

Hi,

In message “Re: Embedding 1.9”
on Wed, 9 Jan 2008 18:45:44 +0900, Edwin P. [email protected]
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.

On Jan 9, 2008, at 4:17 AM, Edwin P. 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,

Dave

— Yukihiro M. [email protected] wrote:

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

rgds,
Edwin.

  ________________________________________________________

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

On Wed, Jan 09, 2008 at 03:56:34PM +0900, Dave T. wrote:

I know it seems like I’m being awkward: I’m honestly not. I just want
to tell PickAxe readers how to do this correctly, and every way I’ve
tried in the last day or so has had some kind of problem associated
with it.

And I’m not trying to be pedantic; I’d like to know the “right” way to
do this as well.

I’ve recently added support for embedding to interpreter to Rice (Ruby
Interface for C++ Extensions), and I’d like to abstract away the details
so it works the same on either 1.8 or 1.9.

I’m yet to find a solution that I like even on 1.8, because there are
numerous calls to exit() in the interpreter – which can be dangerous to
use in a C++ application (it bypasses cleanup of objects declared on the
stack).

Paul

On Wed, Jan 09, 2008 at 03:03:49AM +0900, Dave T. 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…

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

— Dave T. [email protected] wrote:

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

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.

  ________________________________________________________

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