questions about embedding ruby

  • Thread starter Basile STARYNKEVITCH
  • Start date
B

Basile STARYNKEVITCH

Dear All,

(I'm re-asking in a simpler way some previously asked questions)

I'm using ruby1.8 under Linux (Debian/sid x86); I compiled ruby1.8
with gcc-3.3

I have the file myscript.rb

################ file myscript.rb
# -*- ruby -*- script myscript.rb
def sayhello(name)
$stderr.printf("hello %s\n", name)
$stderr.flush
end

$stderr.printf("loaded myscript.rb\n")
$stderr.flush
################ end of myscript

I also have the following C program:

################ file testemb_ruby.c
// file testemb_ruby.c
#include <stdio.h>
#include <stdlib.h>
#include <ruby.h>

int
main (int argc, char **argv)
{
VALUE res = 0;
int state = 0;
char *script = 0;
char *cmd = 0;
ruby_init ();
ruby_init_loadpath (); /* to find the libraries */
if (argc > 1)
{
script = argv[1];
printf ("loading ruby script %s\n", script);
ruby_script (script);
rb_load_file (script);
printf ("after load_file errinfo=");
rb_p (ruby_errinfo);
}
if (argc > 2)
cmd = argv[2];
else
cmd = "sayhello(\"world\")";
printf ("before eval %s\n", cmd);
res = rb_eval_string_protect (cmd, &state);
printf ("after eval state=%d res=", state);
rb_p (res);
printf ("after eval errinfo=");
rb_p (ruby_errinfo);
return state;
} // end of main

// eof testemb_ruby.c
################ end of testemb_ruby.c

I'm compiling testemb_ruby.c with ruby1.8 by

cc -g -O -Wall -O -g -I /usr/local/lib/ruby/1.8/i686-linux \
testemb_ruby.c -o testemb_ruby -L/usr/local/lib/ruby/1.8/i686-linux \
-lruby_1.8-static -ldl -lcrypt -lm

I'm running it with testemb_ruby myscript.rb and I am getting

loading ruby script myscript.rb
after load_file errinfo=nil
before eval sayhello("world")
after eval state=6 res=nil
after eval errinfo=#<NoMethodError: (eval):9: undefined method `sayhello' for main:Object>

I have some questions:

1. why the loading of myscript.rb don't show the "loaded myscript.rb"
message (without giving any errors)?

2. why the eval of the 'sayhello("world")' fails after having loaded
myscript.rb which defines the sayhello function?

3. If I run irb1.8 and type load("myscript.rb") and then
sayhello("world") it does work (by saying hello to me)

regards
 
S

Sean O'Dell

Basile said:
Dear All,

(I'm re-asking in a simpler way some previously asked questions)

I'm using ruby1.8 under Linux (Debian/sid x86); I compiled ruby1.8
with gcc-3.3

I have the file myscript.rb

################ file myscript.rb
# -*- ruby -*- script myscript.rb
def sayhello(name)
$stderr.printf("hello %s\n", name)
$stderr.flush
end

$stderr.printf("loaded myscript.rb\n")
$stderr.flush
################ end of myscript

I also have the following C program:

################ file testemb_ruby.c
// file testemb_ruby.c
#include <stdio.h>
#include <stdlib.h>
#include <ruby.h>

int
main (int argc, char **argv)
{
VALUE res = 0;
int state = 0;
char *script = 0;
char *cmd = 0;
ruby_init ();
ruby_init_loadpath (); /* to find the libraries */
if (argc > 1)
{
script = argv[1];
printf ("loading ruby script %s\n", script);
ruby_script (script);
rb_load_file (script);
printf ("after load_file errinfo=");
rb_p (ruby_errinfo);
}
if (argc > 2)
cmd = argv[2];
else
cmd = "sayhello(\"world\")";
printf ("before eval %s\n", cmd);
res = rb_eval_string_protect (cmd, &state);
printf ("after eval state=%d res=", state);
rb_p (res);
printf ("after eval errinfo=");
rb_p (ruby_errinfo);
return state;
} // end of main

// eof testemb_ruby.c
################ end of testemb_ruby.c

I'm compiling testemb_ruby.c with ruby1.8 by

cc -g -O -Wall -O -g -I /usr/local/lib/ruby/1.8/i686-linux \
testemb_ruby.c -o testemb_ruby -L/usr/local/lib/ruby/1.8/i686-linux \
-lruby_1.8-static -ldl -lcrypt -lm

I'm running it with testemb_ruby myscript.rb and I am getting

loading ruby script myscript.rb
after load_file errinfo=nil
before eval sayhello("world")
after eval state=6 res=nil
after eval errinfo=#<NoMethodError: (eval):9: undefined method `sayhello' for main:Object>

I have some questions:

1. why the loading of myscript.rb don't show the "loaded myscript.rb"
message (without giving any errors)?

2. why the eval of the 'sayhello("world")' fails after having loaded
myscript.rb which defines the sayhello function?

3. If I run irb1.8 and type load("myscript.rb") and then
sayhello("world") it does work (by saying hello to me)

regards

Well, cmd is pointing to an area of the stack which no longer exists
when the if statement returns. Subsequent calls to printf and calls
inside rb_eval_string_protect are probably stomping around on the
string. Before I looked elsewhere, I'd fix that.

Change your code to this, and try again:

int
main (int argc, char **argv)
{
VALUE res = 0;
int state = 0;
char *script = 0;
char *cmd = 0;
char *defaultcmd = "sayhello(\"world\")";
ruby_init ();
ruby_init_loadpath (); /* to find the libraries */
if (argc > 1)
{
script = argv[1];
printf ("loading ruby script %s\n", script);
ruby_script (script);
rb_load_file (script);
printf ("after load_file errinfo=");
rb_p (ruby_errinfo);
}
if (argc > 2)
cmd = argv[2];
else
cmd = defaultcmd;
printf ("before eval %s\n", cmd);
res = rb_eval_string_protect (cmd, &state);
printf ("after eval state=%d res=", state);
rb_p (res);
printf ("after eval errinfo=");
rb_p (ruby_errinfo);
return state;
} // end of main


Sean O'Dell
 
T

ts

B> // file testemb_ruby.c

write it like this

svg% cat testembed_ruby.c
#include <stdio.h>
#include <stdlib.h>
#include <ruby.h>

int execute(int argc, char **argv)
{
int state = 0;
char *script = 0;
char *cmd = 0;
VALUE res = 0;

if (argc > 1) {
script = argv[1];
printf ("loading ruby script %s\n", script);
ruby_script (script);
rb_load_protect (rb_str_new2(script), Qfalse, &state);
printf ("after load_file errinfo=");
rb_p (ruby_errinfo);
}
if (argc > 2)
cmd = argv[2];
else
cmd = "sayhello(\"world\")";
printf ("before eval %s\n", cmd);
res = rb_eval_string_protect (cmd, &state);
printf ("after eval state=%d res=", state);
rb_p (res);
printf ("after eval errinfo=");
rb_p (ruby_errinfo);
return state;
}

int main (int argc, char **argv)
{
ruby_init ();
ruby_init_loadpath (); /* to find the libraries */
return execute(argc, argv);
} // end of main
svg%


svg% testembed_ruby myscript.rb
loading ruby script myscript.rb
loaded myscript.rb
after load_file errinfo=nil
before eval sayhello("world")
hello world
after eval state=0 res=#<IO:0x400a0258>
after eval errinfo=nil
svg%



Guy Decoux
 
T

ts

S> ts wrote:
[...][...]
S> That's interesting; does this way work because Ruby marks the stack and
S> it was being loaded within an if block, and moving the load calls to a
S> permanent place on the stack solves the problem?

No, read carefully my example and the original message. In the original
message there is rb_load_file(), but I use rb_load_protect()

* rb_load_file() read a file and compile it into an AST

* rb_load_protect() call rb_load() but trap all errors (to be sure to
don't crash the executable if ruby find an error)
* rb_load() call rb_load_file() *and then* execute the nodes.


Now if it's written like this

this is to try to protect the VALUE res, if ruby call the GC


Guy Decoux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top