lua-users home
lua-l archive

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


Yes, that's what I was trying to say. So, in all the cases the a_meta.__index receives the a table. Thanks for the clarification :-)

2014-10-21 12:13 GMT+02:00 Philipp Janda <siffiejoe@gmx.net>:
Am 21.10.2014 um 10:07 schröbte Paco Zamora Martínez:
You make the point:

"the arguments of the `__index` call might not be the top level object
depending on how deep the chain is"

Which rules define the top level object?

With "top level object" I meant the thing in front of the colon operator (the `o` in `o:foo()`), which is also the first table that has its `__index` triggered. It is not an official term.


In the example send by Daurnimator, the __index in the first level is
receiving the caller object. So, in case of a second level of indirection,
it will receive the previous level metatable? So, given whatever a object,
its metatable b, and metatable of metatable c, the __index of b will
receive a, and the __index of c will receive b as argument.

No. If `a_meta` is the metatable of table `a` and contains an `__index` function, that `__index` function will always receive table `a` as first parameter even if that `__index` function is triggered at the end of an `__index` chain. See for yourself:

    local function foo_method( self )
      print( "method foo called with self:", self )
    end

    local a = {}
    local a_meta = {
      __index = function( t, k )
        print( "a_meta.__index function called with:", t )
        return foo_method
      end,
      __tostring = function() return "a" end,
    }
    setmetatable( a, a_meta )

    local b = {}
    local b_meta = {
      __index = a,
      __tostring = function() return "b" end,
    }
    setmetatable( b, b_meta )

    local c = {}
    local c_meta = {
      __index = b,
      __tostring = function() return "c" end,
    }
    setmetatable( c, c_meta )

    local d = {}
    local d_meta = {
      __index = c,
      __tostring = function() return "d" end,
    }
    setmetatable( d, d_meta )

    a:foo()
    b:foo()
    c:foo()
    d:foo()


Philipp







--
Pako ZM :)
http://cafre.dsic.upv.es:8080/~pako/