Implement immutability for Int, Float, Bool, and Str types; add freeze_table function for Tuple
This commit is contained in:
parent
05756f9289
commit
971cbbc8a2
@ -2,9 +2,31 @@ local oop = require("oop")
|
|||||||
|
|
||||||
local Types = {}
|
local Types = {}
|
||||||
|
|
||||||
|
local function freeze_table(t)
|
||||||
|
return setmetatable({}, {
|
||||||
|
__index = t,
|
||||||
|
__newindex = function()
|
||||||
|
error("Tuple is immutable", 2)
|
||||||
|
end,
|
||||||
|
__len = function()
|
||||||
|
return #t
|
||||||
|
end,
|
||||||
|
__pairs = function()
|
||||||
|
return pairs(t)
|
||||||
|
end,
|
||||||
|
__ipairs = function()
|
||||||
|
return ipairs(t)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
local function IntDef(cls)
|
local function IntDef(cls)
|
||||||
|
local base_newindex = cls.__newindex
|
||||||
|
|
||||||
function cls.__init(this, value)
|
function cls.__init(this, value)
|
||||||
|
rawset(this, "__frozen", false)
|
||||||
this.value = math.floor(tonumber(value) or 0)
|
this.value = math.floor(tonumber(value) or 0)
|
||||||
|
rawset(this, "__frozen", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
function cls.__add(a, b)
|
function cls.__add(a, b)
|
||||||
@ -36,11 +58,22 @@ local function IntDef(cls)
|
|||||||
function cls.to_number(this)
|
function cls.to_number(this)
|
||||||
return this.value
|
return this.value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cls.__newindex(this, key, value)
|
||||||
|
if rawget(this, "__frozen") and key ~= "__fields" then
|
||||||
|
error("Int is immutable", 2)
|
||||||
|
end
|
||||||
|
return base_newindex(this, key, value)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function FloatDef(cls)
|
local function FloatDef(cls)
|
||||||
|
local base_newindex = cls.__newindex
|
||||||
|
|
||||||
function cls.__init(this, value)
|
function cls.__init(this, value)
|
||||||
|
rawset(this, "__frozen", false)
|
||||||
this.value = tonumber(value) or 0.0
|
this.value = tonumber(value) or 0.0
|
||||||
|
rawset(this, "__frozen", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
function cls.__add(a, b)
|
function cls.__add(a, b)
|
||||||
@ -72,6 +105,13 @@ local function FloatDef(cls)
|
|||||||
function cls.to_number(this)
|
function cls.to_number(this)
|
||||||
return this.value
|
return this.value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cls.__newindex(this, key, value)
|
||||||
|
if rawget(this, "__frozen") and key ~= "__fields" then
|
||||||
|
error("Float is immutable", 2)
|
||||||
|
end
|
||||||
|
return base_newindex(this, key, value)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function ListDef(cls)
|
local function ListDef(cls)
|
||||||
@ -161,10 +201,11 @@ local function TupleDef(cls)
|
|||||||
local base_newindex = cls.__newindex
|
local base_newindex = cls.__newindex
|
||||||
|
|
||||||
function cls.__init(this, items)
|
function cls.__init(this, items)
|
||||||
|
rawset(this, "__frozen", false)
|
||||||
if type(items) == "table" then
|
if type(items) == "table" then
|
||||||
this.items = { table.unpack(items) }
|
this.items = freeze_table({ table.unpack(items) })
|
||||||
else
|
else
|
||||||
this.items = {}
|
this.items = freeze_table({})
|
||||||
end
|
end
|
||||||
rawset(this, "__frozen", true)
|
rawset(this, "__frozen", true)
|
||||||
end
|
end
|
||||||
@ -372,8 +413,12 @@ local function SetDef(cls)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function BoolDef(cls)
|
local function BoolDef(cls)
|
||||||
|
local base_newindex = cls.__newindex
|
||||||
|
|
||||||
function cls.__init(this, value)
|
function cls.__init(this, value)
|
||||||
|
rawset(this, "__frozen", false)
|
||||||
this.value = not not value
|
this.value = not not value
|
||||||
|
rawset(this, "__frozen", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
function cls.__tostring(this)
|
function cls.__tostring(this)
|
||||||
@ -383,11 +428,22 @@ local function BoolDef(cls)
|
|||||||
function cls.__eq(a, b)
|
function cls.__eq(a, b)
|
||||||
return a.value == b.value
|
return a.value == b.value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cls.__newindex(this, key, value)
|
||||||
|
if rawget(this, "__frozen") and key ~= "__fields" then
|
||||||
|
error("Bool is immutable", 2)
|
||||||
|
end
|
||||||
|
return base_newindex(this, key, value)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function StrDef(cls)
|
local function StrDef(cls)
|
||||||
|
local base_newindex = cls.__newindex
|
||||||
|
|
||||||
function cls.__init(this, value)
|
function cls.__init(this, value)
|
||||||
|
rawset(this, "__frozen", false)
|
||||||
this.value = tostring(value or "")
|
this.value = tostring(value or "")
|
||||||
|
rawset(this, "__frozen", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
function cls.__len(this)
|
function cls.__len(this)
|
||||||
@ -401,6 +457,13 @@ local function StrDef(cls)
|
|||||||
function cls.__tostring(this)
|
function cls.__tostring(this)
|
||||||
return this.value
|
return this.value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cls.__newindex(this, key, value)
|
||||||
|
if rawget(this, "__frozen") and key ~= "__fields" then
|
||||||
|
error("Str is immutable", 2)
|
||||||
|
end
|
||||||
|
return base_newindex(this, key, value)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Types.Int = oop.class(IntDef)
|
Types.Int = oop.class(IntDef)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user