lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


The piece of code of real interest is the code in lvm.c that implements
OP_SELF. Essentially what the language gives you at that point is a target
value and a string. OP_SELF needs to come up with a callable entity (e.g., a
function) and a target.

The existing implementation for OP_SELF is effectively:

    function OP_SELF( obj, msg )
        return obj[ msg ], obj
    end

Examples of alternative implementations would include the __methods
metatable patch which provides a metatable entry akin to __index but
accessed only by the colon operator.

    function metafield( t, k )
        local mt = getmetatable( t )
        return mt and rawget( mt, k )
    end

    function lookup( handler, t, k )
        if handler == nil then
            return nil
        elseif type( handler ) == "table" then
            return handler[ k ]
        else
            return handler( t, k )
        end
    end

    function OP_SELF_methods( obj, msg )

        local f = rawget( obj, msg )

        if f == nil then
            f = lookup( metafield( obj, "__methods" ), obj, msg )
        end

        if f == nil then
            f = lookup( metafield( obj, "__index" ), obj, msg )
        end

        return f, msg
 
    end

If one redefines OP_SELF, then there probably need to be the following
additional enhancements since the necessary information may not be readily
available:

lua_getmethod( lua_State* L ): A C API extension that takes the top two
objects on the stack as obj and msg and does the appropriate method lookup.

bindmethod( obj, msg ): A Lua function that takes an object and a message
and returns a closure that sends msg to obj with any other parameters passed
to the closure.

hasmethod( obj, msg ): A Lua function that tests for the presence of a
message -- i.e., it tells you whether it would be safe to send the message.

Mark