lua-users home
lua-l archive

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


2014-05-02 10:49 GMT+02:00 Thomas Jericke <tjericke@indel.ch>:

> Now I can't use the colon operator as 'obj.cmd:funct(1)' would be 'obj.cmd.funct(cmd, 1)' but I
> want obj.cmd.funct(obj, 1). Anyway my solution was simple, obj.cmd.funct is a userdata that has a __call in
> its metatable that does the call, and it has all the information stored in the userdata that it needs.

Lua functions are anonymous: you can assign them to names
but the function does not know what its name is. The debug
library can make an educated guess which is often right, some
local variable can say what the function thinks its own name is,
but by the time `funct` is called, it does not know whether
it was associated with `obj.cmd.funct` or with `local f` or whatever.

Nothing forces you to call a function that was declared with colon
syntax only as a method; you can always call it plainly with an
explicit first argument.

So to get `funct` to know what `obj` is, the value `obj` is in some sense
an upvalue for `funct`. There are probably all sorts of clever tricks
involving the debug library, but I prefer an explicit `parent` field
in this sort of situation.

> obj = {}; obj.cmd = {parent = obj}
> function obj.cmd:funct(...)
   local parent = self.parent
   if parent and parent.cmd == self then self = parent end
   return self,...
   end
> return obj.cmd:funct(1,2,3)
table: 0xe137f0    1    2    3
> return obj
table: 0xe137f0