LuaでLinkList

awesomeの拡張機能を作るため、Luaをいじっているのだが、 tableの概念の理解のためにも一からLinkListを作ってみる。 双方向に移動できるように作った。 FILOのスタックとして利用するために、 pushとpopを作った。

-- class Link
-- 個々のリンクを管理する
Link = {}
function Link.new (value,previouslink,nextlink)
    local link = {
        value = value,
        next = nextlink,
        previous = previouslink,
    }
    return link
end
-- class LinkList
-- Linkのインスタンスでリストを作る
LinkList = {}
function LinkList.new ()
    local linklist = {
        first = nil,
        last = nil,
        -- for FILO stack use
        push = function (self,value)
            local link = Link.new(value,nil,self.first)
            if link.next then
                link.next.previous = link
            end
            self.first = link
            if not self.last then
                self.last = link
            end
        end,
        pop = function (self)
            local link = self.last
            if not link then
                return nil
            end 
            self.last = link.previous
            if self.last then
                self.last.next = nil
            else
                self.first = nil
            end
            return link.value
        end,
        len = function (self)
            local link = self.first
            local length = 0
            while link ~= nil do
                length = length + 1
                link = link.next
            end
            return length
        end,
    }
    return linklist
end
よくわからないのは、
  • newをLink.newで作るのか、Link:newで作るのか
  • metatableで#演算子を置き換えるにはどうすればいいか
後者は__lenで出きると思ったのだけど、できなかった。 prototypeベースのオブジェクト指向で書いたのは多分初めてなので、 これだけ書くだけで意外と苦戦した。