lua-users home
lua-l archive

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


I've run into this frequently enough to remember that I've run into it
before, but not frequently enough to relegate it to an automatic
pattern...

The scenario is that I have an object that has defined methods in a
template (table). Typically, I'd define the index so that it pointed
to a table of methods:

setmetatable(obj, {__index = My_Class_Table})

However, I'm dealing with something along the lines of xpath and would
like to allow the user to "walk" any index path and as a final action,
call the remote method, which is the last element. This requires a
more sophisticated __index metamethod that returns a table if there is
nothing found in the class table. This table is adorned with a the
same metatable as the object itself, where, when called, stashes the
command away and walks backwards to the main object..... you know...
code is better:

```lua
local Template = {}
local path_mt = {}

local function path_walk (self, command, ...)
  if rawget(self, "__parent") == nil then
    return self:handlers(command, ...)
  else
    return path_walk(self.__parent, command, self.name, ...)
  end
end


--> *****Subject of this email: (t, self)***** <--

local function path_call (t, self, ...)
  if self.__parent then
    return path_walk(self.__parent, self.name, ... )
  else
    error("Attempt to call remote object '%s' without a command
specified." % {self.name})
  end
end

local function path_index(self, i)
  if Template[i] then
    return Template[i]
  else
    self.path[i] = setmetatable({name = i, __parent = self, path = {}}, path_mt)
    return self.path[i]
  end
end


path_mt.__index = path_index
path_mt.__call = path_call



function Template:method_a (args)
  --stuff
end
function Template:method_b(args)
  --more stuff
end

local make_new_object = function(args)
   local self = {}

   ---do stuff to initialize self.

  setmetatable(self, path_mt)
  return self

end
```

I don't have any ideas here or suggestions or criticisms or
proposals... The issue is that when I'm calling native methods, I'm
using the "object:method(arguments)" syntax and this does not work
well when mixed with the way that call works.

I think I prefer the "consistency" of always including the table as
the first argument ("t") in the __call metamethod, where consistency
is defined as "relative to the other metamethods." Also, I rarely mix
the colon syntax and what I've got going on here.

But, when I can't figure out why I'm getting two copies of self: one
foisted upon me by Lua and one because I called the function with a
colon, I can't help but feel like I created a clash between two
different ways to use Lua that should not be mixed.

I throw this out there, in case anyone else had an insight or a
comment on this... anti-pattern?

Thanks for the therapy. :)


-Andrew