lua-users home
lua-l archive

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


Per the recent discussions on class systems, I thought I would toss in a few
items on the mechanisms not policy front.

1. Cloning functions with new environments. It would be useful if there were
a way to clone off a function with a new environment. setfenv currently
changes the environment on the function which can be useful but gets in the
way of plumbing that might do things like give methods environments in which
super was available as a global giving a link the next function up the call
chain.

For example, the class system support in Lightroom works by having a class
constructor function that takes a sequence of method sets (possibly
recursive) which it then linearizes and uses to build a method table for the
instances. As it stands, we just override functions with no super-call
support. With adjustable function environments, we could support custom
chaining based on the linearization and methods could do things like:

    function method( self, ... )
        super( self, ... )
        -- do other stuff
    end

I don't have any great ideas for syntax/naming. The point is that setfenv
doesn't work because it will change all uses of the function rather than
allowing one to create a single version with a different environment.

2. Access to the base object in a chain of __index invocations.

Our class system supports a properties mechanism so that one can define
setters and getters for virtual fields. This makes some other code
relatively convenient to write, but it comes with the downside of making
method lookup slower. The issue is that on a proerty lookup, we need to not
just find a function, we need to run it to get the result value. Hence, our
objects have __index metamethods that look like the following:

    -- Assume upvalues methods and properties containing relevant data
    -- for the class.

    function __index( t, k )
        local m = methods[ k ]
        if m then return m end
        local p = properties[ k ]
        if p then return p( t, k ) end
        error( "Unknown method or property: " .. tostring( k ) )
    end

We could speed method dispatch by avoiding the function overhead if we could
define the methods table as an __index table for the class with the
properties logic tied to an __index metamethod for the methods table. That
doesn't work, however, because when that metamethod gets called, what it
will be passed is the methods table and it won't have access to the object
instance.

Implementation suggestion: __index metamethods receive a third parameter
giving the base object that triggered the __index chain.

Mark