lua-users home
lua-l archive

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


Lua arguably has as much of an object model as COM from the standpoint that
it has a standard way to call things in an object-based fashion. COM doesn't
support inheritance unless you roll it together yourself.

Okay. COM interfaces give you namespace resolution which Lua lacks. I can
think of interesting syntactic extensions to get there such as:

    obj:[ msg ]( .... )

This is equivalent to obj[ msg ]( obj, ... ). The point being that one can
then use things other than strings as message identifiers and thereby avoid
naming collisions. Of course, one can also just go for longer message names.

COM also through its interface notion has a standard way to test for
behavior, but this can at least to some extent be addressed through
introspection. To make it efficient, a few more conventions might be in
order.

But the fundamental lesson from COM is that implementation inheritance
doesn't matter all that much and that a standardized API can let one roll
one's own with respect to isolated subsystems.

----

One thing that is harder to do in Lua than in some object models (though not
COM since it isn't supported in COM) is to create
attributes/properties/whatever -- i.e., the appearance of fields that invoke
code when read and written. You can do this with proxy tables and __index
and __newindex methods but it comes at the expense of efficient method
lookup.

To get efficient method lookup (both with respect to space and time), the
thing to do is to add a metatable with a table for the __index entry
containing the methods. But to process attribute lookup, we need to actually
run a function after doing the lookup. This makes the code look something
like:

    function __index( t, k )
        local method = methods[ k ]
        if method then
            return method
        end
        return attributes[ k ]( t, k )
    end

One can even get a decent error message for missing attributes by putting a
good __index table on the attributes table.

If __index functions could get the table at the base of the chain as well as
the most recent table in the chain, however, we could move more of this
logic out of Lua and into the VM by setting things up as follows:


    setmetatable( methods, { __index = function( t, k, base )
        return attributes[ k ]( base, k )
    end } )

    setmetatable( obj, { __index = methods } )

Now, failures to find the method turn directly to attribute lookup and
processing, but successes in finding the methods run without any other Lua
code outside the VM.

Mark