lua-users home
lua-l archive

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


On Wed, Oct 23, 2002 at 12:27:43AM -0500, Matt Holmes wrote:
> the function tag method is never invoked, I simply get the standard error 
> about not being able to call a string value. Am I using the function tag 
> method incorrectly, or am I just minterpreting its meaning?

The function tag method allows you to call a table itself as a function.

Example:

tag = newtag()
settagmethod(tag, "function", function(table, ...) print("called on ", table, "with ", arg) end

table = {}
settag(table, tag)

table(1, 2, 3, 4, 5, 6)

So, what is this useful for? I would say that this is a somewhat
esoteric feature of Lua, but it does come in handy occasionally. One
application turns up if you need to set the properties of a "function"
before you call it. In this case, you could store them in the table,
and set the function tag method for it. 

Another useful application comes when you interface with other
languages. Tolua, for example, creates a table for every bound C++
class under the same name. A C++ object is instantiated thusly:

obj = Class:new(a, b, c)
...
obj:delete()

This is awkward and not at all in the spirit of Lua as a whole. We use
the function tag method to provide a more natural syntax, which also
takes care of automatic deletion of the object:

-- helper function that forwards a constructor call to the corresponding
-- new() call and takes ownership
function constructor_forwarder(...)
   -- arg[1] contains the class object
   local object = call(arg[1].new, arg)
   -- the allocated object will be garbage collected
   tolua.takeownership(object)
   return object
end

settagmethod(tag(Class), "function", constructor_forwarder)

This then allows the more natural (from a C++ point of view) syntax:

obj = Class(a, b, c)

and the obj:delete() is not necessary at all.

A similar trick also makes working with LuaJava more
palatable. Instead of calling:

Integer = javaBindClass("java.lang.Integer")
i = javaNew(Integer, 2),

setting the function tag method for the table "Integer" allows the
more natural:

i = Integer(2)

Hope this helps
- Christian