A (yet another, I know ) simple class library for Lua

Busted Luacheck Docs

Features

  • Inheritance (subclass)
  • Constructor call downwards the hierarchy (from parent to child)
  • Table-oriented constructor (the only parameter of a constructor is a table)
  • RTTI (isA, isSubclassOf)

Installation

Either copy the subclass.lua file to the location accessible by your project or :

luarocks make

in the root directory of this repo (see luarocks).

P.S. Someday I will probably publish this as a rock so no need to clone the repo.

Example

describe('Tutorial', function()
    local Class = require('subclass')
    -- Create a new class
    local Drawable = Class:subclass('Drawable')

    -- Constructor. Called every time a new instance is created.
    -- self is the instance itself. No need to return anything from the constructor.
    function Drawable:new()
        self.color  = self.color or { 0, 0, 0 }
        self.weight = self.weight or 1
    end

    -- Static fields. Can be overridden by a child class
    Drawable.nDim = 2
    Drawable.name = 'drawable'

    -- Method. Can be overridden by a child class.
    -- (note: the dot syntax to explicitly express that the self parameter isn't used)
    function Drawable.size(_)
        return nil
    end

    -- Polyline is a Drawable
    local Polyline = Drawable:subclass('Polyline')

    function Polyline:new()
        self.points = self.points or {}
    end

    -- Override static field
    Polyline.name = 'polyline'

    -- Override method
    function Polyline:size()
        if #self.points == 0 then
            return nil
        end

        local minX, minY, maxX, maxY = nil, nil, nil, nil
        for _, p in ipairs(self.points) do
            minX = minX and math.min(p.x, minX) or p.x
            minY = minY and math.min(p.y, minY) or p.y
            maxX = maxX and math.max(p.x, maxX) or p.x
            maxY = maxY and math.max(p.y, maxY) or p.y
        end

        return { x = maxX - minX,
                 y = maxY - minY }
    end

    function Polyline:nPoints()
        return #self.points
    end

    local d = Drawable {
        color = { 1, 1, 1 }
    }

    local p = Polyline {
        weight = 2,
        points = {
            { x = 0, y = 0 },
            { x = 0, y = 1 },
            { x = 1, y = 1 },
            { x = 1, y = 0 },
        }
    }

    it('subclass of', function()
        assert.is.equal(Drawable:isSubclassOf(Class)    , true)
        assert.is.equal(Polyline:isSubclassOf(Class)    , true)
        assert.is.equal(Polyline:isSubclassOf(Drawable) , true)
    end)

    it('instance of', function()
        assert.is.equal(d:isA(Class)    , true)
        assert.is.equal(d:isA(Drawable) , true)
        assert.is.equal(p:isA(Class)    , true)
        assert.is.equal(p:isA(Drawable) , true)
        assert.is.equal(p:isA(Polyline) , true)
    end)

    it('fields', function()
        assert.is.equal(d.name       , Drawable.name )
        assert.is.equal(d.nDim       , Drawable.nDim )
        assert.is.equal(p.super.name , Drawable.name ) -- access the superclass
        assert.is.same(d.color       , { 1, 1, 1 } )
        assert.is.equal(d.weight     , 1 )

        assert.is.equal(p.name   , Polyline.name )
        assert.is.equal(p.nDim   , Drawable.nDim )
        assert.is.same(p.color   , { 0, 0, 0 } )
        assert.is.equal(p.weight , 2 )
    end)

    it('methods', function()
        assert.is.equal(d:size()    , nil)
        assert.is.same(p:size()     , { x = 1, y = 1 })
        assert.is.equal(p:nPoints() , 4)
    end)
end)

Documentation

See here for documentation.

generated by LDoc 1.5.0 Last updated 2025-10-05 08:47:19