classic icon indicating copy to clipboard operation
classic copied to clipboard

Metamethods doesn't works! ;(

Open winterwolf opened this issue 5 years ago • 3 comments

Here is the difference between classic and middleclass:

local MiddleClass = require "middleclass"
local M = MiddleClass("M")


function M:initialize()
  self.pos = {2, 4}
  self.size = {6, 8}
end


function M:__index(key)
  if key == "x" then return self.pos[1]
    elseif key == "y" then return self.pos[2]
    elseif key == "w" then return self.size[1]
    elseif key == "h" then return self.size[2]
    else rawget(self, key)
  end
end


function M:__newindex(key, value)
  if key == "x" then self.pos[1] = value
    elseif key == "y" then self.pos[2] = value
    elseif key == "w" then self.size[1] = value
    elseif key == "h" then self.size[2] = value
    else rawset(self, key, value)
  end
end


local m = M()

assert(m.x == 2)
m.x = 222
assert(m.pos[1] == 222)

print("No errors in MiddleClass.")


local Classic = require "classic"
local C = Classic:extend()


function C:new()
  self.pos = {2, 4}
  self.size = {6, 8}
end


function C:__index(key)
  if key == "x" then return self.pos[1]
    elseif key == "y" then return self.pos[2]
    elseif key == "w" then return self.size[1]
    elseif key == "h" then return self.size[2]
    else rawget(self, key)
  end
end


function C:__newindex(key, value)
  if key == "x" then self.pos[1] = value
    elseif key == "y" then self.pos[2] = value
    elseif key == "w" then self.size[1] = value
    elseif key == "h" then self.size[2] = value
    else rawset(self, key, value)
  end
end


local c = C()

assert(c.x == 2)
c.x = 222
assert(c.pos[1] == 222)

print("No errors in Classic.")

No errors in MiddleClass. luajit: ../lib/classic.lua:58: attempt to call method 'new' (a nil value)

winterwolf avatar Jun 03 '20 11:06 winterwolf

Replace:

  else rawget(self, key)

with:

  else return rawget(C, key) or C.super[key]

rxi avatar Jun 03 '20 12:06 rxi

@rxi Thank you so much sir!

winterwolf avatar Jun 03 '20 12:06 winterwolf

@rxi I'm sorry, but this solution doesn't work well:

local MiddleClass = require "middleclass"
local M1 = MiddleClass("M1")


function M1:initialize()
  self.pos = {2, 4}
  self.size = {6, 8}
end


function M1:__index(key)
  if key == "x" then return self.pos[1]
    elseif key == "y" then return self.pos[2]
    elseif key == "w" then return self.size[1]
    elseif key == "h" then return self.size[2]
    else return rawget(self, key)
  end
end


function M1:__newindex(key, value)
  if key == "x" then self.pos[1] = value
    elseif key == "y" then self.pos[2] = value
    elseif key == "w" then self.size[1] = value
    elseif key == "h" then self.size[2] = value
    else rawset(self, key, value)
  end
end


local M2 = M1:subclass("M2")
local M3 = M2:subclass("M3")
local M4 = M3:subclass("M4")


local m = M4()

assert(m.x == 2)
m.x = 222
assert(m.pos[1] == 222)

print("No errors in MiddleClass.")


local Classic = require "classic"
local C1 = Classic:extend()


function C1:new()
  self.pos = {2, 4}
  self.size = {6, 8}
end


function C1:__index(key)
  if key == "x" then return self.pos[1]
    elseif key == "y" then return self.pos[2]
    elseif key == "w" then return self.size[1]
    elseif key == "h" then return self.size[2]
    else return rawget(C1, key) or C1.super[key]
  end
end


function C1:__newindex(key, value)
  if key == "x" then self.pos[1] = value
    elseif key == "y" then self.pos[2] = value
    elseif key == "w" then self.size[1] = value
    elseif key == "h" then self.size[2] = value
    else rawset(self, key, value)
  end
end

local C2 = C1:extend()
local C3 = C2:extend()
local C4 = C3:extend()

local c = C4()

assert(c.x == 2)
c.x = 222
assert(c.pos[1] == 222)

print("No errors in Classic.")

No errors in MiddleClass. luajit: metatables-oop.lua:59: attempt to index field 'pos' (a nil value)

winterwolf avatar Jun 03 '20 14:06 winterwolf