lua-users home
lua-l archive

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

I was thinking about something similar recently.

For creating simple objects, it is nice that obj:msg() translates to obj.msg( obj ) and hence obj can be just a table. When one builds more sophisticated object systems supporting properties or supporting doesNotUnderstand, it's pretty useful to be able to tell the difference between a property lookup and a method lookup. Lua's existing metamechanisms, however, don't let one do that.

What allowing obj:msg as an expression does is provide access to the one "optimization" that table lookup allows and does so in a safe way. For example, Lua allows one to write:

	local cacheMethod = obj1.msg
	-- intervening code where you forget what's going on
	cacheMethod( obj2 )

Or maybe you cache the method lookup for the first element in an array and run into trouble upon hitting a case where polymorphic lookup is needed.

More commonly, people who get confused between period and colon can end up passing the wrong parameters to method invocations.

So, I could definitely get on board with something like the following:

* obj:msg as an expression returns a function which invokes the current binding of msg for obj or nil if there is no binding (i.e., it's the method equivalent of obj.msg). Essentially, this is an invocation of the SELF opcode followed by using the results to construct a function.

* Both obj:msg and obj:msg() consult a special metamethod to do message lookup. Essentially this is a modification of the SELF opcode.

This would further establish obj:msg() as the "preferred" object- oriented syntax for Lua, but the fact that it exists at all suggests that it is already considered preferable to other approaches. It doesn't make those approaches go away or impair them in anyway, however. It just builds more support around the colon operator. Furthermore, it would make it easier to build systems that detect errors, do special processing for the doesNotUnderstand case, etc..

I am not, however, prepared at this time to give definitive semantics for a __self metamethod. One possibility would be that we would do a normal table lookup, but then turn to __self in preference to __index if it existed.

Finally, it would be good to have a fast way to test for method support. These changes would essentially force the use of obj:msg for any object using the new __self metamethod, but since that actually constructs a closure, it's overkill if all we want is a boolean.