30log icon indicating copy to clipboard operation
30log copied to clipboard

Subclasses retain old members after changes to superclass

Open PyryM opened this issue 9 years ago • 0 comments

If a class member is replaced after another class has extended from it, the derived class retains the old value. However, if a new member is added, the derived class does see the new value. This is because extend both copies all the class members to the derived class (presumably to avoid the performance cost of having to potentially walk up a deeply nested metatable hierarchy), and also sets the superclass to be the metatable of the derived class.

local Fruit = class("Fruit")
function Fruit:print_thing()
  print("Original function!")
end

local Apple = Fruit:extend("Apple")

Fruit.print_thing = function()
  print("Replaced function!")
end

Fruit.new_thing = function()
  print("A function added after extend!")
end

local a_fruit = Fruit()
local an_apple = Apple()
a_fruit:print_thing()  -- Replaced function! [ok]
an_apple:print_thing() -- Original function! [bad]
an_apple:new_thing()   -- A function added after extend! [ok]

I don't have a good solution, so this is more of an FYI that changing classes on the fly (e.g., in a live coding environment) can have unexpected behavior.

PyryM avatar Jan 10 '17 18:01 PyryM