|
On Mon, Oct 20, 2014 at 6:27 AM, Paco Zamora Martínez <pakozm@gmail.com> wrote:Thanks Dirk, but rawget(self,self.v) didn't solve the problem because "self" is not the table "o", so, field v doesn't exist in self table. The key is correct, "baz", but the given self table is not table "o" instance.The problem here is that __index function is not getting "o" table while __index table functions are... I'm curious about if that is an intentional behavior and why. IMHO, it is surprising that both approaches are not producing the same result.--2014-10-20 12:26 GMT+02:00 Dirk Laurie <dirk.laurie@gmail.com>:o:baz() ->2014-10-20 11:42 GMT+02:00 Paco Zamora Martínez <pakozm@gmail.com>:
> local metainstance = {
> __index = {
> foo = function(self) return self.v end,
> },
> }
> setmetatable(metainstance.__index, {
> __index = {
> bar = function(self) return self.v end,
> },
> })
> setmetatable(getmetatable(metainstance.__index).__index, {
> __index = function(self,key)
> if key == "baz" then return rawget(self,v) end
> end,
> })
> local class = {
> new = function(v) local t = {v=v} setmetatable(t, metainstance) return t
> end,
> }
> local o = class.new(5)
> print( o:foo() )
> print( o:bar() )
> print( o:baz() )
>
> The output of this code is:
>
> 5
> 5
> lua: min.lua:24: attempt to call method 'baz' (a nil value)
> stack traceback:
> min.lua:24: in main chunk
> [C]: in ?
>
> because the nested __index function receives as argument a table which is
> not the caller o table, and the rawget(self,v) function returns nil
o.baz(o) ->
o["baz"](o) ->
getmetatable(o).__index"baz"(o) ->
rawget(o,nil) ->
nil
Maybe make that rawget(self,self.v)?
Pako ZM :)I believe that the reasoning includes a mix of performance, avoiding reference loops and design.It maybe helpful to view the table variation as a shortcut that is suitable for the most simple use cases. It may also be helpful to consider that Lua doesn't have a formal object model as much as it has mechanisms to implement object models. That is to say, if Lua had feelings: It might be sympathetic to your requirements but it doesn't view them as uniquely relevant.Besides the speed of a raw lookup, there is the consequence of making long chains of table lookups too easy. Stack traces in Ruby are illustrative of this consequence (although I admit that I know next to nothing about Ruby).By the way you asked your question, I didn't get the sense that you were seeking alternative approaches, so much as wondering why this was the case. Is that correct?-Andrew