Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Chris Larson http://kergoth.com/

« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS 

Lua: API deprecation

What follows is Tem's code to deprecate an API function or table in Lua.

function deprecate(o,name,instead)
	local msg = "%sWarning, deprecated feature "..(name and ("'"..name.."' ") or "").."in use."..(instead and ("  Use '"..instead.."' instead.") or "")
	if(type(o) == "table") then
		return setmetatable({},{__index = function (t,k)
				local _,callpoint = pcall(function() error("",4) end)
				print(string.format(msg,string.gsub(callpoint,"(^w%*%.%w*%:%d+)","%1")))
				return o[k]
			end,
			__newindex = function (t,k,v)
               	local _,callpoint = pcall(function() error("",4) end)
				print(string.format(msg,string.gsub(callpoint,"(^w%*%.%w*%:%d+)","%1")))
				o[k] = v
				return o[k]
			end
		})
	elseif(type(o) == "function") then
		return function(...)
			local _,callpoint = pcall(function() error("",4) end)
			print(string.format(msg,string.gsub(callpoint,"(^w%*%.%w*%:%d+)","%1")))
			return o(unpack(arg))
		end
	end
end


Example Usage:
Ace = {}

function Ace:print(msg)
	print(msg)
end

function foo()
	print("FOO!")
end
ace = deprecate(Ace,"ace","Ace")
FOO = deprecate(foo,"FOO","foo")

FOO()
ace:print("moo")


Output of Example Usage:
./deprecate.lua:38: Warning, deprecated feature 'FOO' in use.  Use 'foo' instead.
FOO!
./deprecate.lua:39: Warning, deprecated feature 'ace' in use.  Use 'Ace' instead.
moo

Lua: Lazy Map Implementation: Round One

Concept code for a lazy map implementation in Lua

require "std.table" -- For memoize

function map(t, f)
    local nt = table.memoize(function (k) return f(t[k]) end)
    local mt = getmetatable(nt)
    function mt:__pairs()
        local k
        local function mynext()
            k,v = next(t, k)
            if k == nil then return nil end
            return k,nt[k]
        end
        return mynext, self
    end
    return nt
end


Example Usage:
require "std.base" -- For better table tostring()

local mylist = {1,3,5,7,9}
local newlist = map(mylist, function(v) return 3 * v - 2 end)
assert(mylist[3] == 5)
assert(newlist[3] == 13)

require "std.base" -- For the pairs() that obeys the __pairs metamethod
print("old:", mylist)
print("new(3*v-2):", newlist)

Lua: Sane Granular Defaults for User Supplied Data

This code is an example of how to implement sane defaults for user supplied data in a generically useful fashion. It was written for use in World of Warcraft User Interface addons, though it would be useful elsewhere.

local mooDB

local defaults = {
    a = {
        foo = "bar"
    },
    b = 1,
    c = {
        bar = "foo"
    },
}

if not mooDB then
    -- NOTE: This would not be in the actual real world code.  This
    -- simulates user data, normally loaded from some sort
    -- of datastore, which is SavedVariables in the case of
    -- World of Warcraft.
    mooDB = {
        c = {
            bop = "whee"
        }
    }
end

function inheritdefaults(t, defaults)
    for k,v in pairs(defaults) do
        if t[k] then
            if type(v) == "table" then
                inheritdefaults(t[k], v)
            end
        end
    end

    local mt = getmetatable(t) or {}
    function mt:__index(k)
        return defaults[k]
    end
    return setmetatable(t, mt)
end

inheritdefaults(mooDB, defaults)

assert(mooDB ~= defaults)
assert(mooDB.a == defaults.a)
assert(mooDB.c ~= defaults.c)
assert(mooDB.a.foo == "bar")
assert(mooDB.b == 1)
assert(mooDB.c.bar == "foo")
assert(mooDB.c.bop == "whee")

Lua: Descending Table Traversal Round 2: Iterator Object

This is some concept code I threw together for Lua to see how feasable it was to make a lua object/table into an iterator that you can manipulate. This iterator descends through all tables and subtables of any queued table. It returns the "path" we're at, as a string, the current table, the key, and the value.

Code:
traverse = {}
function traverse:new(tname)
	local o = {}
	o.names = {}
	o.queue = {}
	o.cur = {
		tbl = nil,
		path = nil,
		state = nil,
	}

	local mt = {}
	function mt:__call(tn)
		return o:iter(tn)
	end
	mt.__index = self
	setmetatable(o, mt)

	if tname then
		o:enqueue(tname)
	end
	return o
end
function traverse:next()
	local v
	local names, queue, cur = self.names, self.queue, self.cur

	local function _poptbl()
		if cur.tbl then
			names[cur.tbl] = nil
		end
		cur.tbl = table.remove(queue, 1)
		cur.path = names[cur.tbl]
		cur.state = nil
	end

	repeat
		-- Find something to return to the user...
		if not cur.state then
			-- Pop a new table off the stack
			_poptbl()
			if not cur.tbl then
				-- No more tables to process
				return nil
			end
		end
		cur.state,v = next(cur.tbl, cur.state)
	until cur.state

	if type(v) == "table" then
		local path = cur.path.."."..cur.state
		names[v] = path
		table.insert(queue, v)
	end
	return cur.path,cur.tbl,cur.state,v
end
function traverse:iter(tname)
	if tname then
		self:enqueue(tname)
	end
	return function(...) return self:next(unpack(arg)) end, nil, nil
end
function traverse:enqueue(tname)
	local v = _G[tname]
	table.insert(self.queue, v)
	self.names[v] = tname
end
function traverse:reset()
	self.names = {}
	self.queue = {}
end
local traverse_mt = {
    __call = function(self, tname)
             	if tname then
             		return self:new(tname):iter()
             	else
             		return self:new()
             	end
             end
}
setmetatable(traverse, traverse_mt)


Example Usage:
foo = {a={},b={},c={"bar"},d={e={},f={"moo"}},1,2,3,4,5}
bar = {"alpha", "beta", "theta", omega = {}}

local mytraverser = traverse()
mytraverser:enqueue("bar")
mytraverser:enqueue("foo")
for p,t,k,v in mytraverser() do
--for p,t,k,v in traverse('foo') do
	print(string.format("%s[%s] = %s",tostring(p),tostring(k),tostring(v)))
end


Output from Example Usage:
bar[1] = alpha
bar[2] = beta
bar[3] = theta
bar[omega] = table: 0x510650
foo[1] = 1
foo[2] = 2
foo[3] = 3
foo[4] = 4
foo[5] = 5
foo[a] = table: 0x5102d0
foo[c] = table: 0x510370
foo[b] = table: 0x510320
foo[d] = table: 0x5103c0
foo.c[1] = bar
foo.d[e] = table: 0x5104c0
foo.d[f] = table: 0x510510
foo.d.f[1] = moo
« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS