Sorry for the no subject... I hope this is better
Jesse
Hmm, I don't even know what an anonymous module is :)
> J> The second problem is that it works now. It actually does, but I guess
> J> it isn't the best way to do things. Well thats not the problem, the
> J> problem is that whenever I call puts or print to write something to
> J> stdout my application crashes (SEGVT) on rb_func_undef_alloc (or
> J> something like that). Could this be caused by using threads?
>
> Do you ruby threads or system threads ?
>
System threads. I don't use threading myself but GTK+ (or pango, I'm not
sure) seems to thread.
J> Hmm, I don't even know what an anonymous module is :)
See
rb_load_protect(VALUE name, int wrap, int *state)
if `wrap' is true, ruby will create an anonymous module and will load the
script in it. For example
svg% cat b.rb
#!/usr/bin/ruby
def tt
puts "tt"
end
svg%
svg% ruby -e 'load("b.rb"); tt'
tt
svg%
now in an anonymous module
svg% ruby -e 'load("b.rb", true); tt'
-e:1: undefined local variable or method `tt' for main:Object (NameError)
svg%
J> System threads. I don't use threading myself but GTK+ (or pango, I'm not
J> sure) seems to thread.
ruby don't really like system threads : try to avoid it if you can
Guy Decoux
> J> System threads. I don't use threading myself but GTK+ (or pango, I'm not
> J> sure) seems to thread.
>
> ruby don't really like system threads : try to avoid it if you can
Well, I'll try to get them out then, but I'm not sure this can be done.
Jesse
J> script right? But maybe I can just load the file instead of requiring
J> it. The problem then is that when I load a script file it just executes
J> and I'm not able to just call a function in the script.
The problem is not that you _can_ load the file, you *must* load it
because ruby lost all definitions after the load
Guy Decoux
Okay, I might get it know. So if I'm understanding this all well then
after each load all previous memory, definitions, classes, all of it is
lost and I can begin clean? This is indeed just what I need.
The problem I have know is that I used to call this from C to let the
script register its functions:
rb_funcall(rb_mKernel, rb_intern("register_functions"), 0);
This worked okay when I rb_required the file. But now that I'm using
rb_load_file this fails. I suppose the register_functions from the
loaded file is not sitting in the rb_mKernel module than?:
[15:43:15] # script_register_functions: registering functions in
/home/jesse/.gnome2/gnoemoe/scripts/run.rb
[15:43:15] # script_error: Error while executing Ruby code: undefined
method `register_functions' for Kernel:Module
[15:43:15] # script_error: Ruby backtrace:
[15:43:15] # script_error: from
/home/jesse/.gnome2/gnoemoe/scripts/run.rb:39
What should I specify for 'module' in the rb_funcall?
Jesse
J> This worked okay when I rb_required the file. But now that I'm using
J> rb_load_file this fails. I suppose the register_functions from the
J> loaded file is not sitting in the rb_mKernel module than?:
The loaded file need to call the register_functions, i.e. rather than
define a register_function the file must call any method that it want
J> What should I specify for 'module' in the rb_funcall?
You can't specify a module : the module don't exist after the load this is
why ruby lost the definitions.
Guy Decoux
Now I'm really confused. I can't call any functions that sit in the
loaded file. I can't define functions from within C that the ruby script
I load can call. What CAN I do then. I need to let my C application know
what methods there are. Every method registered is a little script. And
I need to execute these methods from my C application.
> You can't specify a module : the module don't exist after the load this is
> why ruby lost the definitions.
So how to call a function from the loaded file...
Jesse
J> Now I'm really confused. I can't call any functions that sit in the
J> loaded file.
yes,
J> I can't define functions from within C that the ruby script
J> I load can call.
no,
svg% cat b.rb
#!/usr/bin/ruby
def tt
A::tt()
end
tt
svg%
svg% cat x.rb
#!/usr/bin/ruby
module A
module_function
def tt
puts "A::tt"
end
end
load("b.rb", true)
svg%
svg% x.rb
A::tt
svg%
J> So how to call a function from the loaded file...
submit a RCR ? :-)
Guy Decoux
Funny thing, cause I got it working now. What I do is I load the script
file using rb_load_file. Then I call ruby_exec. After that I start
defining the classes and global objects/functions the scripts can use.
And with eval_string I can call the functions defined in the script
(such as register_functions and the registered functions themselfs :))
So I hope this is a good way to do this.
Jesse
J> So I hope this is a good way to do this.
Look in eval.c how is called rb_load_file()
Guy Decoux
I don'treally get your point... But I'm using rb_load now, and its still
working :)
Jesse
> So how to call a function from the loaded file...
can't you do something evil like this?
~ > cat a.rb
def user_method
p 42
end
~ > cat b.rb
class Wrapped
class << self
module_eval(IO.read('a.rb'))
end
end
Wrapped.user_method
~ > ruby b.rb
42
b.rb is obviously the C bit.
-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it.
| --Dogen
===============================================================================
J> I don'treally get your point... But I'm using rb_load now, and its still
J> working :)
Look at rb_load_protect() and you don't need ruby_exec() if you use
rb_load()
Guy Decoux
Hmm, rb_load() SEGV's my application. rb_load_file without ruby_exec
will not register functions and do the things I want it to do.
rb_load_file and then ruby_exec will do, so I'm sticking to this.
Jesse
J> rb_load_file and then ruby_exec will do, so I'm sticking to this.
rb_load_file + ruby_exec is similar to rb_load *except* that many things,
that ruby need, are not done.
See the source of rb_load() (in this function eval_node(self, node) is
similar to your call to ruby_exec())
Guy Decoux
GTK+ and Pango may be compiled with native thread *support*, but they
(and most Glib-based toolkits) are single-threaded event-driven APIs.
If you're having reentrancy problems, you could try recompiling GTK+
(and its dependencies, Glib, ATK, and Pango) with thread support
disabled.
Lennon
I like Paul's follow up: "Give ruby a try, but don't expect it to
solve all your problems. It will not make breakfast for you in bed or
greet you with a kiss." ;)
The article makes excellent use of the word "arbitrary" too!
Sean O'Dell
I don't think this is an option as I'm developing this for debian and it
uses the debian packages. I looked a bit further and maybe its nog GTK+
or Pango. My guess is it has to do with Gnome (or bonobo). But it seems
to work for now. Maybe I'll look into it later.
Jesse
Hey, speak for yourself...
Hal
I'm beginning development of an embedded ruby application,
where I want to run ruby in a separate system thread
(not the main thread), and run an OpenGL renderer (C/C++)
in the main thread.
However I plan to never have the main thread call the ruby
interpreter directly, or vice-versa. The ruby thread and
the renderer thread will communicate via a command queue
data structure, with appropriate access synchronization.
And data owned by the ruby garbage collector will never
be seen by other threads.
What I'm wondering is, does this sound like a fairly trouble-
free approach? Or am I still stepping into dangerous
territory here? I'm hoping that by keeping the ruby thread
completely separate from the other thread(s) (except for
communication through the queueing mechanism) that I should
be safe from thread-related issues with the ruby interpreter.
However, if what I'm attempting is already known to be
fraught with problems, I'd definitely like to know! :)
Thanks for any insight and advice.
Regards,
Bill
Lennon
Isolating the Ruby runtime in a single thread should protect most of
the runtime's internal data structures from synchronization problems,
but I don't think that the core is implemented with an eye towards
cooperating with other threads on things like signals.
If you're only allowing access to the Ruby runtime from a single
thread anyway, you might be better off just forking a child process
that handles the Ruby scripting, and having the two communicate via
some sort of RPC.
Lennon
I'm not sure I've followed the discussion, but this is something I use
to load (or require) a script and get an actual object (a module, in
fact) that has the methods (and constants) defined in the script:
http://redshift.sourceforge.net/script/
The basic idea is just "module_eval(IO.read(file))", but there's some
convenience stuff around that.