Skip to content

Instantly share code, notes, and snippets.

@richardhundt
Last active August 29, 2015 13:57
Show Gist options
  • Save richardhundt/9900812 to your computer and use it in GitHub Desktop.
Save richardhundt/9900812 to your computer and use it in GitHub Desktop.
Shine final table fields
function fields(schema is Table)
module fields
local slots = { }
-- create slot objects to use as keys so that we can trip __set__
-- every time for a type check (just one way to do it, there are more)
for k, v in schema do
slot = { }
function slot.set(o, v)
if v is schema[k] then
rawset(o, self, v)
else
error("%{schema[k]} expected got %{typeof(v)}", 2)
end
end
function slot.get(o)
return rawget(o, self)
end
slots[k] = slot
end
-- standard fallback
__get__(k)
if slots[k] then
return slots[k].get(self)
else
error("attempt to get member: %{k} in %{self}", 2)
end
end
-- standard fallback
__set__(k, v)
if slots[k] then
slots[k].set(self, v)
else
error("attempt to set member: %{k} in %{self}", 2)
end
end
-- hook for module include
function self.__included(into)
into.$slots = slots
if into.__base and into.__base.$slots then
setmetatable(into.$slots, { __index = into.__base.$slots })
end
end
end
return fields
end
class Point
include fields { x = Number, y = Number }
end
class Point3D extends Point
include fields { z = Number }
end
p = Point3D(1,2)
p.x = 10
p.z = 100
p.foo = 42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment