Lua::State represents Lua interpreter state which is one thread of execution.
Public Class methods
Converts a Ruby closure proc
to a Lua function in Lua::State
represented by state
. Note that you generally do not need to
call this function explicitly: any proc
or lambda
passed as a value for table assignment will be automagically converted to
Lua closure.
static VALUE rbLuaFunction_initialize(int argc, VALUE* argv, VALUE self) { VALUE rbLuaState, ref = Qnil, func; rb_scan_args(argc, argv, "11", &rbLuaState, &func); if(rb_obj_class(rbLuaState) != cLuaState) rb_raise(rb_eTypeError, "wrong argument type %s (expected Lua::State)", rb_obj_classname(rbLuaState)); VALUE rbState = rb_iv_get(rbLuaState, "@state"); rb_iv_set(self, "@state", rbState); lua_State* state; Data_Get_Struct(rbState, lua_State, state); VALUE proc = Qnil; if(TYPE(func) == T_FIXNUM) ref = func; else if(rb_respond_to(func, rb_intern("call"))) proc = func; else rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc)", rb_obj_classname(func)); if(ref == Qnil) { lua_pushlightuserdata(state, (void*) proc); lua_pushcclosure(state, call_ruby_proc, 1); ref = rlua_makeref(state); lua_pop(state, 1); // don't allow GC to collect proc rb_iv_set(self, "@proc", proc); } rlua_add_ref_finalizer(rbState, ref, self); rb_iv_set(self, "@ref", ref); return self; }
Public Instance methods
Compares this
with other
. May call
__eq
metamethod.
static VALUE rbLua_equal(VALUE self, VALUE other) { lua_State* state; Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state); int equal; rlua_push_var(state, self); // stack: |this|... rlua_push_var(state, other); // |othr|this|... equal = lua_equal(state, -1, -2); // |othr|this|... lua_pop(state, 2); // ... return equal ? Qtrue : Qfalse; }
Returns environment table of Lua::State or Lua::Function.
static VALUE rbLua_get_env(VALUE self) { lua_State* state; Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state); VALUE ref; rlua_push_var(state, self); // stack: |this|... lua_getfenv(state, -1); // |envi|this|... ref = rlua_makeref(state); // |envi|this|... lua_pop(state, 2); // ... return rb_funcall(cLuaTable, rb_intern("new"), 2, self, ref); }
Sets environment table for Lua::State or Lua::Function. table
may be a Lua::Table or a Hash.
static VALUE rbLua_set_env(VALUE self, VALUE env) { lua_State* state; Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state); if(rb_obj_class(env) != cLuaTable && TYPE(env) != T_HASH) rb_raise(rb_eTypeError, "wrong argument type %s (expected Lua::Table or Hash)", rb_obj_classname(env)); rlua_push_var(state, self); // stack: |this|... rlua_push_var(state, env); // |envi|this|... lua_setfenv(state, -2); // |this|... lua_pop(state, 1); // ... return env; }
Compares this
with other
without calling any
metamethods.
static VALUE rbLua_rawequal(VALUE self, VALUE other) { lua_State* state; Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state); int equal; rlua_push_var(state, self); // stack: |this|... rlua_push_var(state, other); // |othr|this|... equal = lua_rawequal(state, -1, -2); // |othr|this|... lua_pop(state, 2); // ... return equal ? Qtrue : Qfalse; }
Invokes a Lua function in protected environment
(like a Lua xpcall
).
One value returned in Lua is returned as one value in Ruby; multiple values returned in Lua are returned as an array of them in Ruby. This convention allows usage of identical code for calling methods with multiple return values in both languages.
While you can easily call Lua procedures and use
their return values, returning multiple values from Ruby is not that easy.
RLua cannot guess whether array returned by Ruby function is a ‘real’ array
or just several return values, so there is a Lua.multret proxy method for that
purpose. Ruby return values constructed with multret
method
are automatically unpacked to multiple return values. Example:
state = Lua::State.new state.p = lambda{ |*args| p *args } state.f1 = Lua::Function.new(state, lambda{ [ 1, 2, 3 ] }) state.f2 = Lua::Function.new(state, lambda{ Lua.multret( 1, 2, 3 ) }) state.__eval("p(f1())") # results in { 1.0, 2.0, 3.0 } Lua table # shown as array state.__eval("p(f2())") # results in 1.0, 2.0, 3.0 Lua multiple return values # shown as three separate values
Any Lua error that has appeared during the call
will be raised as Ruby exception with message equal to Lua error message. *Lua
error messages are explicitly converted to strings with
lua_tostring
function.* Lua errors
are mapped as follows:
- LUA_ERRMEM
-
NoMemError is raised.
- LUA_ERRRUN
-
RuntimeError is raised.
Note that if any uncatched exception is raised in Ruby code inside Lua::Function it will be propagated as Lua error. *In this case the backtrace is lost!* Catch your exceptions in Ruby code if you want to keep their backtraces.
This ‘drawback’ is intentional: while it is technically possible to re-raise the same Exception object, the backtrace will lead to re-raise point anyway.
static VALUE rbLuaFunction_call(VALUE self, VALUE args) { lua_State* state; Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state); int i; VALUE retval; rlua_push_var(state, self); // stack: |this|... for(i = 0; i < RARRAY_LEN(args); i++) rlua_push_var(state, RARRAY_PTR(args)[i]); // |argN-arg1|this|... retval = rlua_pcall(state, RARRAY_LEN(args)); // ... return retval; }