lua-users home
lua-l archive

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


Has anyone else implemented a Smalltalk-like forwarding mechanism with Lua?
This is different from inheritance - if an none of an object's parent
classes respond to a message, it calls that object's "forward" method
with the message as an argument.

I found a way to implement this for method calls (see below) but it
causes problems for failed variable accesses (they return a the
forward function instead of nil)

I've considered doing everything with methods, but I'm not
happy with having to do my variable set/gets with methods of
a different name or having to move variables into a subtable.

Anyone found a better way to do this?

==========================================

$debug

function inherit(table, index)
    if ( index == "parent" ) then return nil end 	-- avoid loops
    local parent = table.parent		-- access parent object

    if ( type(parent) == "table" ) then	-- see if it's a table
        return parent[index]       		-- this may call Inherit again
    else
	if ( rawgettable(table, "className") ~= nil ) then  -- see if it's an object
		forwardMethod = index; -- set the global forward method
		write("inherit - forwarding message '"..tostring(index).."'\n")
		return forward; -- neat trick, have it return our forward function
	end
	return nil
   end
end

OldIndex = setfallback("index", inherit)

function forward(forwardObject,...)
    local argCount = tableLength(arg)
    local returnValue

    write("forward("..forwardMethod..")\n");
    if ( forwardSelector == "forward" ) then return nil end -- avoid loops
    if ( forwardSelector == "className" ) then return nil end -- avoid loops

    if ( argCount == 0 ) then
	returnValue = forwardObject:forward(forwardMethod)
    end
    if ( argCount == 1 ) then
	returnValue = forwardObject:forward(forwardMethod, arg[1])
    end
    if ( argCount == 2 ) then
	returnValue = forwardObject:forward(forwardMethod, arg[1], arg[2])
    end
    if ( argCount == 3 ) then
	returnValue = forwardObject:forward(forwardMethod, arg[1], arg[2], arg[3])
    end

    forwardMethod = nil
    return returnValue
end