From f4b7eca18f8ddd2b68a3a22a0fa589fd7480004a Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Tue, 18 Jan 2022 18:47:38 +0100 Subject: [PATCH] Add func.memoize --- func.lua | 18 ++++++++++++++++-- test.lua | 10 ++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/func.lua b/func.lua index 11405a9..2ba0465 100644 --- a/func.lua +++ b/func.lua @@ -1,6 +1,6 @@ -- Localize globals -local error, coroutine, math, modlib, unpack - = error, coroutine, math, modlib, unpack +local error, coroutine, math, modlib, unpack, select, setmetatable + = error, coroutine, math, modlib, unpack, select, setmetatable -- Set environment local _ENV = {} @@ -35,6 +35,20 @@ function values(...) return function() return unpack(args) end end +function memoize(func) + return setmetatable({}, { + __index = function(self, key) + local value = func(key) + self[key] = value + return value + end, + __call = function(self, arg) + return self[arg] + end, + __mode = "k" + }) +end + -- Equivalent to `for x, y, z in iterator, state, ... do callback(x, y, z) end` function iterate(callback, iterator, state, ...) local function loop(...) diff --git a/test.lua b/test.lua index a8d445d..1a6369c 100644 --- a/test.lua +++ b/test.lua @@ -53,6 +53,16 @@ do end assert(next(tab) == nil) assert(func.aggregate(func.add, 1, 2, 3) == 6) + local called = false + local function fun(arg) + assert(arg == "test") + local retval = called + called = true + return retval + end + local memo = func.memoize(fun) + assert(memo(arg) == false) + assert(memo(arg) == false) end -- string