Luaのクラス

久しぶりの更新になってしまった。

今回は、Luaのクラス例のメモ。
世間の例などを参考に自作してみた。

luaの仕様が謎なのは

setmetatable(t, delegate)

じゃなくて

setmetatable(t, {__index=delegate})

にするところ。
おかげで

delegate.__index=delegate

というまじないが必要になるがなんか意図があるのだろうか・・・。


(追記)
意味はあった。
__index以外にも__add, __subとかわりといろんな機能があるみたいだ。
http://sugarpot.sakura.ne.jp/yuno/html/lua51_manual_ja.html#2.8


以下クラス定義関数の例。
ruby風味のコンストラクタ(initializeメソッド)と継承を仕込んでみた。

-- classを定義する
function define_class(name, base_table)
  -- new class
  local class_table={}
  class_table.__index=class_table

  -- extend
  if base_table then
    setmetatable(class_table, base_table)
  end

  -- constructor
  class_table.new=function(...)
    local instance={}
    setmetatable(instance, class_table)
    if instance.initialize then
      --instance.initialize(...)
      -- こそっと修正
      instance:initialize(...)
    end
    return instance
  end

  -- set global
  _G[name]=class_table
end

--------------------------------------------------------------------------------
-- 使う
--------------------------------------------------------------------------------
define_class("Base")

function Base:base_display()
  print "Base"
end

function Base:display()
  base_display()
end

--------------------------------------------------------------------------------
define_class("Extend", Base)

function Extend:display()
  print("Extend", self.x, self.y)
end

function Extend:initialize(x, y)
  self.x=x
  self.y=y
end

function Extend:move(x, y)
  self.x=self.x+x
  self.y=self.y+y
end

--------------------------------------------------------------------------------
local ex=Extend:new(10, 20)
ex:base_display()
ex:move(5, 2)
ex:display()

あと関数呼び出し時の:のシンタックスシュガーがいまいち解りにくいと思ったら
定義と呼び出しのペアで理解していないからだったのでメモ。

t={}

-- 定義
function t:method()
-- function t.method(self)のシンタックスシュガー
end

-- 呼び出し
t:method()
-- t.method(t)のシンタックスシュガー