Class: Lua::RefObject

Inherits:
Object
  • Object
show all
Defined in:
rubyluabridge.cpp

Overview

The Ruby representation of non-primitive objects in Lua.

***************************************************************************

Instance Method Summary (collapse)

Constructor Details

- (Object) Lua::RefObject.new

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.



# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.new -> result
 * 
 * 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;
}

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) Lua::RefObject.method_missing

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.



# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.method_missing -> result
 * 
 * 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 <tt>=</tt> 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 '<tt>_</tt>' at the end, it is treated as an method invocation,
 * passing itself as a parameter.  This is to emulate the '<tt>:</tt>' 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 );
}

Instance Method Details

- (Object) Lua::RefObject

Returns the value indexed at key in the RefObject.

Raises RuntimeError if the RefObject is not indexable.



# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.[key] -> value
 *
 * 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;
}

- (Object) Lua::RefObject

Assigns value to be indexed at key in the RefObject. Returns the value for chaining.

Raises RuntimeError if the RefObject is not indexable.



# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.[key] = value -> value
 *
 * 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
}

- (Integer) Lua::RefObject.__length

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.

Returns:

  • (Integer)


# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.__length -> int
 * 
 * Returns the 'length' of the RefObject.  
 * 
 * According to the {Lua manual}[http://www.lua.org/manual/5.1/manual.html#lua_objlen]:
 *    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;
}

- (Object) Lua::RefObject.__metatable

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



# File 'rubyluabridge.cpp'

/* call-seq: 
 *      Lua::RefObject.__metatable -> Lua::Table
 *
 * 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;
}

- (Object) Lua::RefObject.__metatable=(Lua::Table)

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



# File 'rubyluabridge.cpp'

/* call-seq: 
 *      Lua::RefObject.__metatable= Lua::Table -> Lua::Table
 *
 * 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;
}

- (Object) Lua::RefObject.__state

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



# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.__state -> Lua::State
 * 
 * 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;
}

- (Integer) Lua::RefObject.__type

Returns the type id of the underlying Lua object.

Returns:

  • (Integer)


# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.__type -> int
 *
 * 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;
}

- (true) Lua::State.indexable?

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

Returns:

  • (true)


# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::State.indexable? -> true
 * 
 * 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;
}

- (true) Lua::RefObject.indexable?

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

Returns:

  • (true)


# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.indexable? -> true
 * 
 * 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;
}

- (true) Lua::RefObject.new_indexable?

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

Returns:

  • (true)


# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.new_indexable? -> true
 * 
 * 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;
}

- (Object) Lua::RefObject.new_table_at(key)

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

Raises RuntimeError if the RefObject is not indexable.



# File 'rubyluabridge.cpp'

/* call-seq: 
 *        Lua::RefObject.new_table_at key -> Lua::Table
 * 
 * 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;
}

- (String) Lua::RefObject.to_s

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

Returns:

  • (String)


# File 'rubyluabridge.cpp'

/* call-seq: 
 *      Lua::RefObject.to_s -> string
 * 
 * Invokes the Lua function {tostring}[http://www.lua.org/manual/5.1/manual.html#pdf-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;
}