• 全局变量相关

    function declare_global(name, value)
      rawset(_G, name, value or false)
    end
    
    function delete_global(name)
      rawset(_G, name, nil)
    end
    
    function get_global(name)
      return rawget(_G, name)
    end
    
    function unrequire(name)
      if package.loaded[name] then
        package.loaded[name] = nil
        if get_global(name) then
          delete_global(name)
        end
      end
    end
    
  • 只读 table

    -- 设置记录 error 的 traceback 深度
    local function _traceback()
      return '\\n' .. traceback('lua traceback', 3)
    end
    
    function readonly_table(t)
      assert(type(t) == 'table', 'invalid type')
      setmetatable(t, {
        __newindex = function(_, n)
          log.error('attempt to write to undeclared global variable: ' .. n .. _traceback())
        end,
        __index = function(_, n)
          log.error('attempt to read undeclared global variable: ' .. n .. _traceback())
        end,
      })
    end
    
  • 设置继承关系/创建类的实例

    ---@param parent table
    ---@param child table?
    function new_instance(parent, child)
      child = child or {}
      for k, v in pairs(parent) do
        if type(v) == 'table' then
          child[k] = {}
        end
      end
      setmetatable(child, {__index = parent})
      return child
    end
    
  • 遍历

    function switch(case)
      return function(cases)
        local f = cases[case] or cases.default
        if f then
          return f(case)
        end
      end
    end
    
    ---@param tbl table
    ---@param func fun(k:any, v:any)
    function foreach(tbl, func)
      if tbl == nil or type(tbl) ~= 'table' then return end
      for k, v in pairs(tbl) do
        func(k, v)
      end
    end
    
  • 一个简单的高精度计时器(需要 socket 库)

    socket = require 'socket'
    local __timer_t = 0
    local __timer_s = nil
    
    ---@param str string?
    function start_timer(str)
      __timer_t = socket.gettime()
      __timer_s = str or 'timer'
    end
    
    ---@param str string?
    function stop_timer(str)
      local t = socket.gettime() - __timer_t
      log.error(__timer_s, string.format('%.3f ms', t * 1000), str)
    end