lua-users home
lua-l archive

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


On Wed, Jan 14, 2015 at 7:51 PM, Dave Hayden <dave@panic.com> wrote:
> On Jan 14, 2015, at 3:20 PM, Steven Degutis <sbdegutis@gmail.com> wrote:
>>
>>> I want to synthesize properties on the base class using __index and __newindex so that they're available to all instances.
>>
>> To add methods to "all instances" of a class, you just add methods to
>> the table that's the __index field on every instance's metatable, like
>> so: [...]
>
> Okay, but if I want to define an __index function to synthesize a property, I seem to be out of luck: The metatable is passed into __index(self, key), not the instance object.
>
> Can someone verify that Lua just doesn't work that way?
>
> -D
>
>

No, the instance is passed in, not the metatable. You can have both, however.

```
local mt = {}

mt.__index = function(self, i)
   assert(mt ~= self and type(self) == "table")
  return mt.some_method(self, i)
end

function mt:some_method(i)
   return self
end

local obj = setmetatable({}, mt)

assert(obj.foo == obj)

```

Notice that I have access to mt inside of mt.__index, because mt is an
upvalue. Notice that the index handler returns self and self is equal
to the obj table. (I didn't test the above. let me know if it doesn't
work)

Also, note that when you assign `__index` to a table(`mt.__index =
mt`), it is not-quite only short hand for `mt.__index = function(self,
i) return mt[i] end`.

In the table assignment, it is a raw access. In the function
assignment, it's whatever you want. The second example is doing a
normal lookup and will use the an `__index` method on `mt`, if there
is one. That might be something to keep in mind when trying to get a
lookup chain going.

--Andrew