class Lua::State
The Ruby representation of a lua_State.
Public Class Methods
Creates a new Lua::State.
options is a hash of options. If no options are specified, the default is { :loadlibs => :all }.
loadlibs: Invokes Lua::State.__loadlibs on the new Lua::State, passing the value of :loadlibs.
Raises NoMemoryError if the state cannot be allocated, or ArgumentError if the value of :loadlibs is invalid.
static VALUE rlua_State_initialize( int argc, VALUE* argv, VALUE self ) { rlua_State* pRLState; Data_Get_Struct( self, rlua_State, pRLState ); // create new Lua state pRLState->Lstate.reset( luaL_newstate(), lua_close_deleter() ); if ( !pRLState->getState() ) rb_raise( rb_eNoMemError, "lua_State memory allocation failed" ); RLB_DEBUG_PRINT( "state init: ptr:%p L:%p\n", pRLState, pRLState->getState() ); // if there is no arguments (or nil first value), load all if ( argc == 0 || NIL_P(argv[0]) ) { luaL_openlibs( pRLState->getState() ); return self; } // otherwise, it has to be a hash Check_Type( argv[0], T_HASH ); // process "loadlibs" VALUE libs = rb_hash_aref( argv[0], ID2SYM(rb_intern("loadlibs")) ); rlua_State_loadlibs( self, libs ); // OK if nil return self; }
Public Instance Methods
Returns the value indexed at key in the Lua::State's globals table.
VALUE rlua_State_getindex( VALUE self, VALUE key ) { rlua_State* pRLstate; Data_Get_Struct( self, rlua_State, pRLstate ); lua_State* L = pRLstate->getState(); marshal_ruby_to_lua_top( L, key ); lua_gettable( L, LUA_GLOBALSINDEX ); // marshal the result to Ruby VALUE result = marshal_lua_to_ruby( self, L, -1 ); lua_pop( L, 1 ); return result; }
Assigns value to be indexed at key in the Lua::State's globals table.
Returns the value for chaining.
VALUE rlua_State_setindex( VALUE self, VALUE key, VALUE val ) { rlua_State* pRLstate; Data_Get_Struct( self, rlua_State, pRLstate ); lua_State* L = pRLstate->getState(); marshal_ruby_to_lua_top( L, key ); marshal_ruby_to_lua_top( L, val ); lua_settable( L, LUA_GLOBALSINDEX ); return val; // return val for chaining }
Returns the globals table of this Lua::State. It is an instance of the Lua::Table class.
static VALUE rlua_State_globals( VALUE self ) { rlua_State* pRLState; Data_Get_Struct( self, rlua_State, pRLState ); lua_State* L = pRLState->getState(); lua_pushvalue( L, LUA_GLOBALSINDEX ); VALUE result = marshal_lua_to_ruby( self, L, -1 ); lua_pop( L, 1 ); return result; }
Loads the specified Lua standard libraries into the Lua::State.
If libs is not specified, all libraries are loaded. Otherwise, if libs is a symbol, that library is loaded. Special symbols are :all, which loads all libraries, and :none which loads no libraries. If libs is an Array, all symbols in the Array are loaded (in the order specified); in this case, :all and :none are ignored; an empty Array will load no libraries. If none of the above fits, an ArgumentError is raised.
Supported libraries are:
-
base
-
package
-
table
-
io
-
os
-
string
-
math
-
debug
static VALUE rlua_State_loadlibs( VALUE self, VALUE libs ) { rlua_State* pRLState; Data_Get_Struct( self, rlua_State, pRLState ); lua_State* L = pRLState->getState(); // if it is empty or :all, load all // if it is a symbol, load that the lib it matches // if it is :none, load none // if it is an array, load all its symbols (:all is ignored here) // otherwise, load none if ( NIL_P(libs) ) { luaL_openlibs( L ); } else if ( TYPE(libs) == T_SYMBOL ) { const char* libname = rb_id2name( SYM2ID(libs) ); if ( !strcmp(libname, "all") ) luaL_openlibs( L ); else if ( !strcmp(libname, "none") ) {} // load none on :none else load_std_library_by_name( L, libname ); } else if ( TYPE(libs) == T_ARRAY ) { int i; for ( i = 0; i < RARRAY_LEN(libs); i++ ) { VALUE entry = RARRAY_PTR(libs)[i]; if ( TYPE(entry) == T_SYMBOL ) { const char* libname = rb_id2name( SYM2ID(entry) ); load_std_library_by_name( L, libname ); } } } else rb_raise( rb_eArgError, "loadlibs must be Nil, a Symbol, or an Array of symbols" ); return self; }
Returns the registry table of this Lua::State. It is an instance of the Lua::Table class.
As the Lua Registry is intended for C extensions and the Lua reference system, be careful modifying values stored in this table.
static VALUE rlua_State_registry( VALUE self ) { rlua_State* pRLState; Data_Get_Struct( self, rlua_State, pRLState ); lua_State* L = pRLState->getState(); lua_pushvalue( L, LUA_REGISTRYINDEX ); VALUE result = marshal_lua_to_ruby( self, L, -1 ); lua_pop( L, 1 ); return result; }
Returns this Lua::State itself.
Introduced for parallelism with Lua::RefObject.__state.
static VALUE rlua_State_state( VALUE self ) { return self; }
Return the absolute position of the top of the lua_State's stack.
This is mainly for debugging/testing purposes.
static VALUE rlua_State_top( VALUE self ) { rlua_State* pRLState; Data_Get_Struct( self, rlua_State, pRLState ); int top = lua_gettop( pRLState->getState() ); return INT2NUM( top ); }
Returns whether Lua:State is callable (like via __cal), which it is not.. This is to provide consistency with Lua::RefObject interface.
VALUE rlua_State_is_callable( VALUE self ) { return Qfalse; }
Evaluates the passed string in the Lua::State.
Returns the first value returned by the evaluation.
static VALUE rlua_State_eval( VALUE self, VALUE str ) { // verify and marshal Ruby args to C rlua_State* pRLState; Data_Get_Struct( self, rlua_State, pRLState ); SafeStringValue(str); lua_State* L = pRLState->getState(); // process the string to a chunk int err = luaL_loadbuffer( L, RSTRING_PTR(str), RSTRING_LEN(str), "Lua::State.eval" ); if ( err == LUA_ERRMEM ) rb_raise( rb_eNoMemError, "%s", pop_error_to_buffer(L) ); else if ( err == LUA_ERRSYNTAX ) rb_raise( rb_eSyntaxError, "%s", pop_error_to_buffer(L) ); // pcall the chunk, returning only a single argument // TODO: error handler with stack traceback // TODO: it would be nice to have it configurable whether to print the traceback // TODO: hmmm... the err handler could even be in Ruby? err = lua_pcall( L, 0, 1, 0 ); if ( err == LUA_ERRRUN ) rb_raise( rb_eRuntimeError, "%s", pop_error_to_buffer(L) ); else if ( err == LUA_ERRMEM ) rb_raise( rb_eNoMemError, "%s", pop_error_to_buffer(L) ); else if ( err == LUA_ERRERR ) rb_raise( rb_eFatal, "%s", pop_error_to_buffer(L) ); // marshal the result to Ruby VALUE result = marshal_lua_to_ruby( self, L, -1 ); lua_pop( L, 1 ); return result; }
Evaluates the passed string in the Lua::State.
Returns the all the return values in a Ruby array (with the first result first). If there are no results, an empty array is returned.
static VALUE rlua_State_eval_mult( VALUE self, VALUE str ) { // verify and marshal Ruby args to C rlua_State* pRLState; Data_Get_Struct( self, rlua_State, pRLState ); SafeStringValue(str); lua_State* L = pRLState->getState(); int args_bottom = lua_gettop(L); // process the string to a chunk int err = luaL_loadbuffer( L, RSTRING_PTR(str), RSTRING_LEN(str), "Lua::State.eval" ); if ( err == LUA_ERRMEM ) rb_raise( rb_eNoMemError, "%s", pop_error_to_buffer(L) ); else if ( err == LUA_ERRSYNTAX ) rb_raise( rb_eSyntaxError, "%s", pop_error_to_buffer(L) ); // pcall the chunk, returning only a single argument // TODO: error handler with stack traceback // TODO: it would be nice to have it configurable whether to print the traceback // TODO: hmmm... the err handler could even be in Ruby? err = lua_pcall( L, 0, LUA_MULTRET, 0 ); if ( err == LUA_ERRRUN ) rb_raise( rb_eRuntimeError, "%s", pop_error_to_buffer(L) ); else if ( err == LUA_ERRMEM ) rb_raise( rb_eNoMemError, "%s", pop_error_to_buffer(L) ); else if ( err == LUA_ERRERR ) rb_raise( rb_eFatal, "%s", pop_error_to_buffer(L) ); // marshal the result to Ruby int args_top = lua_gettop(L); int nres = args_top - args_bottom; int li, ri; VALUE ary_res = rb_ary_new2( nres ); for ( li = args_bottom+1, ri = 0; li <= args_top; ++li, ++ri ) rb_ary_store( ary_res, ri, marshal_lua_to_ruby(self, L, li) ); lua_pop( L, nres ); return ary_res; }
Returns whether Lua:State is indexable (via __index), which it is. This is to provide consistency with Lua::RefObject interface.
VALUE rlua_State_is_indexable( VALUE self ) { return Qtrue; }
This method is called by Ruby when it sees an Object can't handle a message. We use it to dispatch to Lua, attempting a lookup of that value in the Lua::State's global table.
If the method name has an '=
' at the end, it is
treated as an assignment, in which case it assigns the first value. It
returns that value for chaining.
The first argument is the symbol of the message name, the rest are its args.
VALUE rlua_State_method_missing( int argc, VALUE* argv, VALUE self ) { rlua_State* pRLstate; Data_Get_Struct( self, rlua_State, pRLstate ); lua_State* L = pRLstate->getState(); Check_Type( argv[0], T_SYMBOL ); ID methodid = SYM2ID( argv[0] ); const char* key = rb_id2name( methodid ); lua_pushvalue( L, LUA_GLOBALSINDEX ); return rlua_method_missing_dispatch( L, key, self, argc, argv ); }
Returns whether Lua:State can create new indices (via __newindex), which it can. This is to provide consistency with Lua::RefObject interface.
VALUE rlua_State_is_new_indexable( VALUE self ) { return Qtrue; }
Creates a new table at the given key. Returns the new table.
VALUE rlua_State_new_table_at( VALUE self, VALUE key ) { rlua_State* pRLstate; Data_Get_Struct( self, rlua_State, pRLstate ); lua_State* L = pRLstate->getState(); marshal_ruby_to_lua_top( L, key ); lua_newtable( L ); VALUE result = marshal_lua_to_ruby( self, L, -1 ); lua_settable( L, LUA_GLOBALSINDEX ); return result; }