Take the 2-minute tour ×

An example in the tutorial section : "Defining Metamethods for a C Type" looks as follows:

local ffi = require("ffi")
typedef struct { double x, y; } point_t;

local point
local mt = {
  __add = function(a, b) return point(a.x+b.x, a.y+b.y) end,
  __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,
  __index = {
    area = function(a) return a.x*a.x + a.y*a.y end,
point = ffi.metatype("point_t", mt)

local a = point(3, 4)

I'm a bit confused about where the "constructor" is, I assume by default point(3,4) is implicity routing 3 -> x and 5 -> y. What about when I want to hang some logic onto the constructor ? Put differently.. How do I specify a non-default constructor ?

I'm wrapping a bunch of c-libraries into object oriented lua code, and I do not care about portability to canonical lua. Specifically I need to hook in the three core functions of object oriented programming for object lifetime management, create , init, destroy. I know destroy will be the __gc method of my types' metatable. So I need to know how to do create and init, and hopefully avoid a default initialization done by luajit.


ffi.new and others have a bunch of rules governing the creation of types (documented in the luajit's ffi semantics page). it's in the semantics section. I'd still like to know what the cleanest way would be to hang custom creators and initializers (that come as part of a c library) into ffi object creation.

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

You'd need to wrap your point call to get what you desire:

local function newpoint ( vals )
    -- Do stuff with vals here?
    return point ( vals )
newpoint {x=5;y=4}

OR you could consider your point function as your create function; and just have an init method...

mt.__index.init = function ( p , x , y )
     p.x = x;
     p.y = y;

local mypoint = point()
mypoint:init ( 1 , 2 )

Note; all objects of the point type already have your metatable applied, so you dont need to attach methods or anything.

It does seem a bit pointless to me.... why do you want to seperate creation and initialization??

share|improve this answer
Hahaha yes, pointless, it kept running through my head. It's a class that creates BSON / JSON objects. There is a init method to reset the class after a document has been created. Then there is a malloc/free create destroy. being a C -> C++ -> lua programmer, I got the deer in the headlight thing :D –  Hassan Syed Feb 22 '12 at 1:36
Small helpful addition: make the init method return the object it's called on, e.g: mt.__index.init = function(p,x,x)p.x,p.y=x,y return p end, so you can do this: mypoint = point():init(1, 3). Not very significant, but quite handy (chaining can make code very neat). –  Deco Feb 22 '12 at 12:13
Thank you deco, every idiom helps :D –  Hassan Syed Feb 22 '12 at 12:56
add comment

Your Answer


