|
On 2012-12-05 12:07 PM, "Wolfgang Pupp" <wolfgang.pupp@gmail.com> wrote:
>
> I like this idea a lot! How does this work, exactly- if an object already
> has an __index function, is a lookup for a generic method only performed
> when the __index- function returns nil (errors?), or not at all?
I want to say the ideal behaviour is that the type metatable is not used at all if an individual metatable is present. This gives the most flexibility: if you want to fall back to the type metatable, you can easily do so in your __index metamethod. But it seems potentially more error-prone too, since you have to remember to add that fallback (and add it to existing code).
To try to clarify...
t, m = {}, {}
m.__index = function(t, k) return nil end
assert(t.pairs == pairs)
setmetatable(t, m)
assert(t.pairs == nil)
m.__index = function(t, k) return getmetatable({})[k] end
assert(t.pairs == pairs)
Another option is to have another field in the metatable telling whether to use the type metatable as a fallback or not, with false meaning no and anything else meaning yes (including nil, so it's default behaviour).
E.g.:
t, m = {}, {}
m.__index = function(t, k) return nil end
assert(t.pairs == pairs)
setmetatable(t, m)
assert(m.__fallback == nil)
assert(t.pairs == pairs)
m.__fallback = false
assert(t.pairs == nil)
I think either method is powerful, but potentially confusing...