xtype

xtype.class
Login

Concepts

Class and Instances

A class is a xtype's type with fields to define behavior for its instances. It has the xtype_* and __meta (when built) special fields.

An instance is a table with behavior defined by a specific class.

Type and Inheritance

Type checking and order of inheritance are already specified by xtype.

A class inherits from its base classes fields, except for the xtype_* and __meta fields.

An instance inherits from its class fields (with inheritance), except for xtype_* and those starting with __, which are special class fields.

Inheritance of fields is not dynamic (cached for performance) and is built by class.build, which must be called for any later changes to the class definition or base classes.

The build of a class is independent of other class builds and will affect all its instances. The class is also partially built from the base classes when created (i.e. the class inheritance, not the instance inheritance).

class.build is already called when using a class for instantiation for the first time; in most cases calling this function is unnecessary because the class is completely defined when used.

Special Methods

Special methods are prefixed by __.

Misc:

method description
construct called at initialization
destruct called at garbage collection

Warning: With Lua 5.1 or LuaJIT, neither the table __gc metamethod or ephemeron tables are implemented, thus a __proxy_gc field will be added to instances of a class with a destructor.

Unary operators:

method description
call like the metamethod
tostring like the metamethod
unm like the metamethod
len like the metamethod
bnot like the metamethod

Binary Operators

xtype op multifunctions are assigned to the corresponding metamethods in the instance metatable.

Private / Protected

There is no private/protected mechanism implemented.

"Private" methods can be achieved with local functions in the class definition.

local function pmethod(self)
end

"Private" instance data can be achieved using a local table in the class definition with weak keys for the instances.

local privates = setmetatable({}, {__mode = "k"})

function Object:__construct()
  privates[self] = { a = 1, b = 2 }
end

function Object:method()
  local p = privates[self]
  p.a = p.a*p.b
end

API

-- Create a new class.
-- Base types can be classes or other xtypes.
--
-- name: human-readable string (doesn't have to be unique)
-- ...: base types, ordered by descending proximity, to the least specific type
-- return created class (an xtype)
class.new(name, ...)
-- ALIAS class(name, ...)

-- Create instance.
-- Will build the class if not already built.
--
-- classdef: class
-- ...: constructor arguments
-- return created instance
class.instantiate(classdef, ...)
-- ALIAS Class(...)

-- Build/re-build the class (class and instance inheritance).
-- Will add the `__meta` field to the class.
--
-- classdef: class
class.build(classdef)

-- Get the class metatable applied to the instances.
-- Will build the class if not already built; useful to apply class behaviour
-- to a custom table.
--
-- classdef: class
-- return metatable
class.meta(classdef)

Examples

Type Checking

A = class("A")
a = A()
xtype.is(A, class) -- true
xtype.is(a, A) -- true

Multiple Inheritance and Override

A = class("A")
function A:test() print("a") end

B = class("B")
function B:test() print("b") end

C = class("C", A, B) -- inheritance from A and B
function C:test() -- force the usage of B:test()
  B.test(self)
end

Constructor Override

A = class("A")
function A:__construct() print("A") end

B = class("B", A)
function B:__construct()
  A.__construct(self) -- call parent A constructor
  print("B")
end

Binary Operator Definition

vec2 = class("vec2")
function vec2:__construct(x, y) self.x, self.y = x, y end

xtype.op.add:define(function(a, b)
  return vec2(a.x+b.x, a.y+b.y)
end, vec2, vec2)