class Lua::State

  1. ext/rlua.c
Parent: Lua

Lua::State represents Lua interpreter state which is one thread of execution.

Public Class methods

Lua::State.new

Creates a new Lua state.

[show source]
static VALUE rbLua_initialize(VALUE self)
{
  lua_State* state = luaL_newstate();
  
  VALUE rbState = Data_Wrap_Struct(rb_cObject, 0, lua_close, state);
  rb_iv_set(self, "@state", rbState);
  
  lua_pushlightuserdata(state, (void*) self);
  lua_setfield(state, LUA_REGISTRYINDEX, "rlua_state");
  
  lua_newtable(state);
  lua_setfield(state, LUA_REGISTRYINDEX, "rlua");
  
  rb_iv_set(rbState, "@refs", rb_hash_new());
  rb_iv_set(rbState, "@procs", rb_ary_new());
  
  return self;
}

Public Instance methods

state[key] -> value

Returns value of a global variable. Equivalent to __env.

[show source]
static VALUE rbLua_get_global(VALUE self, VALUE index)
{
  VALUE globals = rbLua_get_env(self);
  return rbLuaTable_get(globals, index);
}
state[key] = value -> value

Sets value for a global variable. Equivalent to __env = value.

[show source]
static VALUE rbLua_set_global(VALUE self, VALUE index, VALUE value)
{
  return rbLuaTable_set(rbLua_get_env(self), index, value);
}
state.__bootstrap() -> true

Deploys an absolute minimum of functions required to write minimally useful Lua programs. This is really a subset of Lua base library (copied from Lua 5.1 sources) that may be handy if you don’t like standard function layout. All of these functions can be implemented in pure Ruby, but that will slow down Lua code incredibly.

If you want to get familiar layout described in Lua documentation, check ##__load_stdlib function.

Exact list of functions defined: type, next, tonumber, tostring, unpack, select, error, assert, pcall, xpcall.

[show source]
static VALUE rbLua_bootstrap(VALUE self)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);
  
  int nf;
  for(nf = 0; nf < sizeof(stdlib) / sizeof(stdlib[0]); nf++) {
    lua_pushcclosure(state, stdlib[nf].func, 0);
    lua_setglobal(state, stdlib[nf].name);
  }
  
  lua_pushcfunction(state, bootstrap_next);
  lua_pushcclosure(state, bootstrap_pairs, 1);
  lua_setglobal(state, "pairs");
  
  lua_pushcfunction(state, bootstrap_inext);
  lua_pushcclosure(state, bootstrap_ipairs, 1);
  lua_setglobal(state, "ipairs");
  
  return Qtrue;
}
object.__env() -> Lua::Table

Returns environment table of Lua::State or Lua::Function.

[show source]
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);
}
object.__env=(table) -> table

Sets environment table for Lua::State or Lua::Function. table may be a Lua::Table or a Hash.

[show source]
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;
}
state.__eval(code[, chunkname='=<eval>']) -> *values

Runs code in Lua interpreter. Optional argument chunkname specifies a string that will be used in error messages and other debug information as a file name.

Start chunkname with a @ to make Lua think the following is filename (e.g. @test.lua); start it with a = to indicate a non-filename stream (e.g. =stdin). Anything other is interpreted as a plaintext Lua code and a few starting characters will be shown.

[show source]
static VALUE rbLua_eval(int argc, VALUE* argv, VALUE self)
{
  VALUE code, chunkname;
  rb_scan_args(argc, argv, "11", &code, &chunkname);

  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);
  
  if(chunkname == Qnil)
    chunkname = rb_str_new2("=<eval>");

  rlua_load_string(state, code, chunkname);
  
  return rlua_pcall(state, 0);
}
state.__get_metatable(object) -> Lua::Table or nil

Returns metatable of any valid Lua object or nil if it is not present. If you want to get metatables of non-table objects (e.g. numbers) just pass their Ruby equivalent.

[show source]
static VALUE rbLua_get_metatable(VALUE self, VALUE object)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);
  
  rlua_push_var(state, object);                 // stack: |objt|...
  if(lua_getmetatable(state, -1)) {             //        |meta|objt|...
    VALUE ref = rlua_makeref(state);            //        |meta|objt|...
    lua_pop(state, 2);                          //        ...
    
    return rb_funcall(cLuaTable, rb_intern("new"), 2, self, ref);
  } else {                                      //        |objt|...
    lua_pop(state, 1);                          //        ...
    
    return Qnil;
  }
}
state.__load_stdlib(*libs) -> true

Loads Lua standard libraries. There are two ways of calling this function:

If you will call it as #__load_stdlib(:all), it is equivalent to calling C luaL_openlibs function.

If you will pass it symbolized names of separate libraries (like :base), it is equivalent to calling corresponding luaopen_* functions.

Examples:

# Load all standard libraries
state = Lua::State.new
state.__load_stdlib :all
# Load only math, string and table libraries
state = Lua::State.new
state.__load_stdlib :math, :string, :table

Exact list of libraries recognized: :base, :table, :math, :string, :debug, :io, :os, :package. Anything not included in this list will be silently ignored.

[show source]
static VALUE rbLua_load_stdlib(VALUE self, VALUE args)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);
  
  if(rb_ary_includes(args, ID2SYM(rb_intern("all")))) {
    luaL_openlibs(state);
  } else {
    if(rb_ary_includes(args, ID2SYM(rb_intern("base"))))
      rlua_openlib(state, luaopen_base);
    if(rb_ary_includes(args, ID2SYM(rb_intern(LUA_TABLIBNAME))))
      rlua_openlib(state, luaopen_table);
    if(rb_ary_includes(args, ID2SYM(rb_intern(LUA_MATHLIBNAME))))
      rlua_openlib(state, luaopen_math);
    if(rb_ary_includes(args, ID2SYM(rb_intern(LUA_STRLIBNAME))))
      rlua_openlib(state, luaopen_string);
    if(rb_ary_includes(args, ID2SYM(rb_intern(LUA_DBLIBNAME))))
      rlua_openlib(state, luaopen_debug);
    if(rb_ary_includes(args, ID2SYM(rb_intern(LUA_IOLIBNAME))))
      rlua_openlib(state, luaopen_io);
    if(rb_ary_includes(args, ID2SYM(rb_intern(LUA_OSLIBNAME))))
      rlua_openlib(state, luaopen_os);
    if(rb_ary_includes(args, ID2SYM(rb_intern(LUA_LOADLIBNAME))))
      rlua_openlib(state, luaopen_package);
  }
  
  return Qtrue;
}
state.__set_metatable=(object, metatable) -> metatable

Sets metatable for any valid Lua object. metatable can be Lua::Table or Hash. If you want to set metatables for non-table objects (e.g. numbers) just pass their Ruby equivalent.

# Implement concatenation operator for Lua strnigs.
state = Lua::State.new
state.__set_metatable("", { '__add' => lambda{ |a, b| a + b } })
p state.__eval('return "hello," + " world"') # => "hello, world"
[show source]
static VALUE rbLua_set_metatable(VALUE self, VALUE object, VALUE metatable)
{
  lua_State* state;
  Data_Get_Struct(rb_iv_get(self, "@state"), lua_State, state);
  
  if(rb_obj_class(metatable) != cLuaTable && TYPE(metatable) != T_HASH)
    rb_raise(rb_eTypeError, "wrong argument type %s (expected Lua::Table or Hash)", rb_obj_classname(metatable));

  rlua_push_var(state, object);                    // stack: |objt|...
  rlua_push_var(state, metatable);                 //        |meta|objt|...
  lua_setmetatable(state, -2);                     //        |objt|...
  lua_pop(state, 1);                               //        ...
  
  return metatable;
}
state.method_missing(method, *args) -> *values

See Lua::Table#method_missing. Equivalent to __env.method_missing(method, *args).

[show source]
static VALUE rbLua_method_missing(int argc, VALUE* argv, VALUE self)
{
  return rbLuaTable_method_missing(argc, argv, rbLua_get_env(self));
}