Embedding Ruby into Maya, part 3

All is going well. I have the basic functionality up and running of having
ruby inside maya.
However, I have some minor issues/questions pending.

  1. Cleaning/Starting afresh Ruby.

MEL is a persistant language. That is, there is no way to clean up the global
namespace during the whole time maya is open. This tends to work fine for the
type of application it is designed for.
I’ve set my plugin for ruby to work in a similar way. However, I would like to
also have the ability to “restart” a ruby session and clean up everything.
What’s the proper method? ruby_cleanup(), ruby_finalize()? Difference of
both?
I’ve tried using ruby_cleanup(), but once I do, I cannot get any other
See end of message for sample code.

  1. FOX problems, likely related to 1)
    I am having problems running scripts with FOX. FOX runs fine and the window
    pops up, but once the window is closed, it remains around. Re-starting a new
    or same script will give out all sort of weird errors (Thread error on a simple
    put).
    Is it possible that FOX assumes that ruby is running stand-alone and it ends up
    calling some ruby_cleanup() function incorrectly? Or the opposite, that I am
    not calling the right functions that will trash all the FOX widgets properly?

  2. New IO Stream
    I would also like to have a new IO stream to redirect ruby’s $stderr/$stdout or
    print statements. Basically, besides stderr/stdout, Maya has another log
    window for reporting issues. What I would like to do is something similar to
    what can be done with C++ streams. Something along the lines of:

class MayaLog << IO
def sync()
MELLog( @buffer )
@buffer = nil
end
end

That is, everytime the stream reaches a newline and gets sync’ed, the buffer of
the stream would get sent out to a C command of my own(MELLog) and would then
be cleared.
Sadly, I am unable to find any docs describing inheriting from IO. Anyone can
help out?

···

sample code (extracts)

void rubyMEL::initRuby()
{

ruby_init();
ruby_init_loadpath();
// require_libraries();

int result;
rb_eval_string_protect( “require “math3d.so””, &result );
if ( result != 0 )
{
MWARN(“math3d.so ruby library not found. vector and matrix not valid.”);
}

rb_define_global_function(“MEL”, RUBY_METHOD_FUNC(MELevaluate), -1);
rb_define_method(rb_cObject,“toMEL”, RUBY_METHOD_FUNC(toMEL), 0);
}

void rubyMEL::startRuby()
{
char* argv[] = { “ruby”, “-e”, 0 };
#if defined(NT)
int argc = 2;
NtInitialize(&argc, (char***)&argv);
#endif
#if defined(MACOS) && defined(MWERKS)
argc = ccommand(&argv);
#endif

initRuby();
}

void rubyMEL::endRuby()
{
// Get rid of the ruby interpreter, garbage collect everything, etc.
ruby_cleanup(0);
}

/// By the time we call doIt(), startRuby() has already been called at least
once
MStatus rubyMEL::doIt()
{

VALUE ret = rb_eval_string_protect( command.asChar(), &result );
if ( result != 0 )
{
VALUE bang = rb_gv_get("$!");
MFATAL("RUBY ERROR: " << STR2CSTR(bang));
}
rb_eval_string( “$stdout.flush; $stderr.flush” );

//////////////////////////// code does not really go here, just as a
test…
// end and restart ruby afresh after each command.
endRuby();
startRuby();

return MStatus::kSuccess;
}

class MayaLog << IO
def sync()
MELLog( @buffer )
@buffer = nil
end
end

That is, everytime the stream reaches a newline and gets sync’ed, the buffer of
the stream would get sent out to a C command of my own(MELLog) and would then
be cleared.

would’nt a simple StringIO subclass work for this?

require ‘stringio’
=> true
class MelLog < StringIO
def sync
STDERR.puts self.string
end
end
=> nil
a=MelLog.new
=> #MelLog:0x275ab60
a.puts ‘ciao’
=> nil
a.sync
ciao
=> nil

Sadly, I am unable to find any docs describing inheriting from IO. Anyone can
help out?

I believe this has been noted sometimes.
Why we have a big hard to inherit IO Class?

It would be nice, imo, to have some smaller modules mixed in IO and
easy to be imported in any other user defined class.
I.e. Output could be a mix-in based on print(), Input could just need
read() ( and probably we could have a Seekable module)

···

il 16 Mar 2004 04:20:52 GMT, ggarramuno@aol.com (GGarramuno) ha scritto::

would’nt a simple StringIO subclass work for this?

Yes. That seems like what I was looking for.

Any ideas on why FOX does not clean up after itself properly? (ie. what I’m
doing wrong when embedding ruby)