luaのクラスその3

「Programming Lua」読書中。

さらに少し変えてみた。

g_root_class={
  classname="#root#",

  class=function(self)
    return getmetatable(self)
  end,

  super=function(class)
    return getmetatable(class).__index
  end,

  -- constructor
  __call=function(class, ...)
    local instance={}
    setmetatable(instance, class)
    if instance.initialize then
      instance:initialize(...)
    end
    return instance
  end,
}
g_root_class.__index=g_root_class

-- define new class
function define_class(name, base_table)
  base_table=base_table or g_root_class

  -- new class
  local class_table={
    classname=name,
    __tostring=function(self)
      return string.format("<instance of %s>", name)
    end,

    -- constructor
    __call=base_table.__call,
  }
  class_table.__index=class_table

  -- extend
  setmetatable(class_table, base_table)

  -- set global
  _G[name]=class_table
end

--------------------------------------------------------------------------------
define_class("Base")
function Base:initialize()
  print("Base", self)
end

--------------------------------------------------------------------------------
define_class("Extend", Base)
function Extend:initialize()
  print("Extend", self)
  Extend:super().initialize(self)
end

--------------------------------------------------------------------------------
define_class("ExExtend", Extend)
function ExExtend:initialize()
  print("ExExtend", self)
  ExExtend:super().initialize(self)
end

--------------------------------------------------------------------------------
e=ExExtend()

これでClass:newなのかClass.newなのかを悩む必要がなくなった。