# class Lua::RefObject

The Ruby representation of non-primitive objects in Lua.

### Public Class Methods

Lua::RefObject.new → result click to toggle source

Initializes a new Lua::RefObject.

THIS METHOD IS NOT INTENDED TO BE CALLED BY CLIENTS.

TODO: Can we enforce the hiding of this? Only Lua module members should access it.

    static VALUE rlua_RefObject_initialize( VALUE self, VALUE Rstate, VALUE RluaRef )
    {
        rlua_RefObject* pRef;
        Data_Get_Struct( self, rlua_RefObject, pRef );

        RLB_DEBUG_PRINT( "ref init:  self:%d   Rstate:%p  TYPE(Rstate):%d  RluaRef:%d TYPE(RluaRef):%d  luaRef:%d\n",
            (unsigned long)self, (unsigned long)Rstate, (unsigned long)TYPE(Rstate),
            (unsigned long)RluaRef, (unsigned long)TYPE(RluaRef), NUM2INT(RluaRef) );

        pRef->Rstate   = Rstate;
        pRef->Lref     = NUM2INT(RluaRef);

        rlua_State* pRState;
        Data_Get_Struct( Rstate, rlua_State, pRState );
        pRef->Lstate  = pRState->Lstate;

        return self;
    }

### Public Instance Methods

Lua::RefObject.[key] → value click to toggle source

Returns the value indexed at key in the RefObject.

Raises RuntimeError if the RefObject is not indexable.

    VALUE rlua_RefObject_getindex( VALUE self, VALUE key )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        if ( !is_indexable(L, -1) )
        {
            lua_pop( L, 1 );
            rb_raise( rb_eRuntimeError, "(getindex) Lua::RefObject not indexable" );
        }

        marshal_ruby_to_lua_top( L, key );
        lua_gettable( L, -2 );

        // marshal the result to Ruby
        VALUE result = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
        lua_pop( L, 2 );
        return result;
    }

Lua::RefObject.[key] = value → value click to toggle source

Assigns value to be indexed at key in the RefObject.

Returns the value for chaining.

Raises RuntimeError if the RefObject is not indexable.

    VALUE rlua_RefObject_setindex( VALUE self, VALUE key, VALUE val )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        if ( !is_indexable(L, -1) )
        {
            lua_pop( L, 1 );
            rb_raise( rb_eRuntimeError, "(setindex) Lua::RefObject not indexable" );
        }

        marshal_ruby_to_lua_top( L, key );
        marshal_ruby_to_lua_top( L, val );
        lua_settable( L, -3 );

        lua_pop( L, 1 );
        return val;    // return val for chaining
    }

Lua::RefObject.__length → int click to toggle source

Returns the 'length' of the RefObject.

According to the Lua manual:

    Returns the "length" of the value at the given acceptable index:
    for strings, this is the string length; for tables, this is the result
    of the length operator ('#'); for userdata, this is the size of the
    block of memory allocated for the userdata; for other values, it is 0.

    VALUE rlua_RefObject_length( VALUE self )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        size_t len = lua_objlen(L, -1);
        lua_pop( L, 1 );

        VALUE result = INT2NUM(len);
        return result;
    }

Lua::RefObject.__metatable → Lua::Table click to toggle source

Returns the metatable of the underlying Lua object. Return nil if it has no metatable.

    VALUE rlua_RefObject_getmetatable( VALUE self )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );

        if (lua_getmetatable(L, -1) == 0)
            lua_pushnil( L );

        VALUE result = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
        lua_pop( L, 2 );
        return result;
    }

Lua::RefObject.__metatable= Lua::Table → Lua::Table click to toggle source

Sets the metatable for this Lua::RefObject. Returns the passed metatable.

    VALUE rlua_RefObject_setmetatable( VALUE self, VALUE mtable )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );

        marshal_ruby_to_lua_top( L, mtable );
        lua_setmetatable( L, -2 );

        lua_pop( L, 1 );
        return mtable;
    }

Lua::RefObject.__state → Lua::State click to toggle source

Returns the Lua::State this Lua::RefObject belongs to.

    static VALUE rlua_RefObject_state( VALUE self )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );

        return pRefObject->Rstate;
    }

Lua::RefObject.__type → int click to toggle source

Returns the type id of the underlying Lua object.

    VALUE rlua_RefObject_type( VALUE self )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        size_t len = lua_type(L, -1);
        lua_pop( L, 1 );

        VALUE result = INT2NUM(len);
        return result;
    }

Lua::State.indexable? → true click to toggle source

Returns whether Lua:State is callable (like via __cal), which it is not.. This is to provide consistency with Lua::RefObject interface.

    VALUE rlua_RefObject_is_callable( VALUE self )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        VALUE result = is_callable(L, -1) ? Qtrue : Qfalse;

        lua_pop( L, 1 );
        return result;
    }

Lua::RefObject.indexable? → true click to toggle source

Returns whether Lua:State is indexable (via __index), which it is. This is to provide consistency with Lua::RefObject interface.

    VALUE rlua_RefObject_is_indexable( VALUE self )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        VALUE result = is_indexable(L, -1) ? Qtrue : Qfalse;

        lua_pop( L, 1 );
        return result;
    }

Lua::RefObject.method_missing → result click to toggle source

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::RefObject.

The first argument is the symbol of the message name, the rest are its args.

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.

If the method name has a '`_`' at the end, it is treated as an method invocation, passing itself as a parameter. This is to emulate the '`:`' token used in Lua.

    VALUE rlua_RefObject_method_missing( int argc, VALUE* argv, VALUE self )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        Check_Type( argv[0], T_SYMBOL );
        ID methodid = SYM2ID( argv[0] );
        const char* key = rb_id2name( methodid );

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        if ( !is_indexable(L, -1) )
        {
            lua_pop(L, 1);
            rb_raise( rb_eRuntimeError, "Lua::RefObject not indexable, key='%s'", key );
        }

        return rlua_method_missing_dispatch( L, key, pRefObject->Rstate, argc, argv );
    }

Lua::RefObject.new_indexable? → true click to toggle source

Returns whether Lua:State can create new indices (via __newindex), which it can. This is to provide consistency with Lua::RefObject interface.

    VALUE rlua_RefObject_is_new_indexable( VALUE self )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        VALUE result = is_new_indexable(L, -1) ? Qtrue : Qfalse;

        lua_pop( L, 1 );
        return result;
    }

Lua::RefObject.new_table_at key → Lua::Table click to toggle source

Creates a new table at the given key. Returns the new table.

Raises RuntimeError if the RefObject is not indexable.

    VALUE rlua_RefObject_new_table_at( VALUE self, VALUE key )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        if ( !is_indexable(L, -1) )
        {
            lua_pop( L, 1 );
            rb_raise( rb_eRuntimeError, "(setindex) Lua::RefObject not indexable" );
        }

        marshal_ruby_to_lua_top( L, key );
        lua_newtable( L );

        VALUE result = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );
        lua_settable( L, -3 );

        lua_pop( L, 1 );
        return result;
    }

Lua::RefObject.to_s → string click to toggle source

Invokes the Lua function tostring on the object and returns the resulting string.

    VALUE rlua_RefObject_to_s( VALUE self )
    {
        rlua_RefObject* pRefObject;
        Data_Get_Struct( self, rlua_RefObject, pRefObject );
        lua_State* L = pRefObject->getState();

        lua_rawgeti( L, LUA_REGISTRYINDEX, pRefObject->Lref );
        rluaB_tostring( L );

        VALUE result = marshal_lua_to_ruby( pRefObject->Rstate, L, -1 );

        lua_pop( L, 2 );
        return result;
    }