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
On Jan 7, 2008, at 7:41 PM, Mark G. 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
Hi,
In message “Re: Embedding 1.9”
on Tue, 8 Jan 2008 06:44:08 +0900, Dave T. [email protected]
writes:
|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.
Hi,
In message “Re: Embedding 1.9”
on Tue, 8 Jan 2008 13:22:01 +0900, Dave T. [email protected]
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.
Moved over from ruby-talk…
On Jan 7, 2008, at 9:36 PM, Yukihiro M. wrote:
You can load Ruby programs with rb_load().
In 1.9, though, is that enough, or do we then have to call rb_iseq_new/
eval to have the file’s contents actually run (when I try just
rb_load_file, it gets compiled but the code in the file doesn’t appear
to be actually executed).
From an embedding point of view, this is slightly problematic, as
rb_load_file returns VOID *, so it’s hard to pass the parse tree on.
Should I perhaps be calling rb_load(rb_str_new2(“file.rb”, 0)?
Dave
On Jan 7, 2008, at 9:36 PM, Yukihiro M. wrote:
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().
In 1.9, do we also now need to call set_locale()?
Dave
Dave T. wrote:
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
On Jan 7, 2008, at 11:38 PM, Dave T. wrote:
From an embedding point of view, this is slightly problematic, as
rb_load_file returns VOID *, so it’s hard to pass the parse tree on.
Should I perhaps be calling rb_load(rb_str_new2(“file.rb”, 0)?
Also, ruby_init_gems(opt) is a static method in ruby.c, and so can’t
be called from code that embeds Ruby (it could be called via
process_options(), but that really does too much). A solution might be
to change the calling sequence to
void
ruby_init_gems(disable_gems)
{
VALUE gem;
gem = rb_define_module(“Gem”);
rb_const_set(gem, rb_intern(“Enable”), disable_gems);
Init_prelude();
}
and change the call to
ruby_init_gems(opt->disable_gems ? Qfalse : Qtrue);
Dave
On 08/01/2008, Yukihiro M. [email protected] wrote:
However, calling setlocale should not break ruby 1.9 since the
interpreter does it as well 
Thanks
Michal
On Jan 8, 2008, at 12:20 AM, Mark G. wrote:
case TAG_RAISE:
case TAG_FATAL:
Mark:
Are you manually defining the TAG_xxx values somewhere? eval_intern.h
isn’t installed onto the user side on my box.
Dave
Dave T. wrote:
appear to be actually executed).
From an embedding point of view, this is slightly problematic, as
rb_load_file returns VOID *, so it’s hard to pass the parse tree on.
Should I perhaps be calling rb_load(rb_str_new2(“file.rb”, 0)?
Dave,
I had to do the following to get it working:
/*
- Forward declarations for Ruby
*/
void *
rb_compile_cstr(const char *f, const char *s, int len, int line);
int main()
{
RUBY_INIT_STACK;
ruby_init();
ruby_init_loadpath();
ruby_script("…");
ruby_run_node(rb_compile_cstr(“yourfile”,
(const char*)“p :hello”,
/* strlen / 8, / line no */ 1));
}
I also had to change some things in YAML/syck when I tried to link
everything statically… but then no .so files work anymore.
Regards,
Michael
On Jan 8, 2008, at 1:59 AM, Michal S. wrote:
However, calling setlocale should not break ruby 1.9 since the
interpreter does it as well 
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
<(08/01/08 16:08) Dave T.>
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
On Jan 8, 2008, at 10:34 AM, Michael N. wrote:
I had to do the following to get it working:
Michael:
For my very basic example, I went with:
int main(int argc, char **argv) {
VALUE result;
ruby_sysinit(&argc, &argv);
RUBY_INIT_STACK;
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”);
printf(“Result = %d\n”, NUM2INT(result));
ruby_finalize();
exit(0);
}
It worries me that there are so many ways of doing this, and so many
init methods that may or may not be needed. It also worries me that
this doesn’t set up the gem environment.
Dave
On Jan 8, 2008, at 11:27 AM, Hugh S. wrote:
rb_require(“sum.rb”);
WRT Michael’s " but then no .so files work anymore." – do you need
the ‘.rb’ in there for that to work?
No, it works fine with rb_require (but not, I believe, with rb_load).
Dave
On Wed, 9 Jan 2008, Dave T. wrote:
int main(int argc, char **argv) {
VALUE result;
ruby_sysinit(&argc, &argv);
RUBY_INIT_STACK;
ruby_init();
ruby_init_loadpath();
rb_require(“sum.rb”);
WRT Michael’s " but then no .so files work anymore." – do you need
the ‘.rb’ in there for that to work?
[...]
ruby_finalize();
exit(0);
}
It worries me that there are so many ways of doing this, and so many init
methods that may or may not be needed. It also worries me that this doesn’t
I thought that: “What I tell you three times is true” ? 
set up the gem environment.
Dave
Hugh, who's just following along, not got into 1.9 yet really.
On Wed, 9 Jan 2008, Dave T. wrote:
On Jan 8, 2008, at 11:27 AM, Hugh S. wrote:
WRT Michael’s " but then no .so files work anymore." – do you need
the ‘.rb’ in there for that to work?
No, it works fine with rb_require (but not, I believe, with rb_load).
Thanks.
Dave
Hugh
On Jan 8, 2008, at 11:05 AM, Mark G. 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…?
That’d get my vote. I’ve copied core on this…
Dave
On Jan 8, 2008, at 3:35 PM, Paul B. wrote:
Your example should catch exceptions:
Agreed: the second version in the book does, but for this one I wanted
to just show the principle. But I didn’t know about ruby_cleanup,
which is neat. Thanks.
Dave