<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: Kergoth's Code Snippets</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sat, 26 Jul 2008 13:18:17 GMT</pubDate>
    <description>DZone Snippets: Kergoth's Code Snippets</description>
    <item>
      <title>Lua: API deprecation</title>
      <link>http://snippets.dzone.com/posts/show/943</link>
      <description>What follows is Tem's code to deprecate an API function or table in Lua.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;function deprecate(o,name,instead)&lt;br /&gt;	local msg = "%sWarning, deprecated feature "..(name and ("'"..name.."' ") or "").."in use."..(instead and ("  Use '"..instead.."' instead.") or "")&lt;br /&gt;	if(type(o) == "table") then&lt;br /&gt;		return setmetatable({},{__index = function (t,k)&lt;br /&gt;				local _,callpoint = pcall(function() error("",4) end)&lt;br /&gt;				print(string.format(msg,string.gsub(callpoint,"(^w%*%.%w*%:%d+)","%1")))&lt;br /&gt;				return o[k]&lt;br /&gt;			end,&lt;br /&gt;			__newindex = function (t,k,v)&lt;br /&gt;               	local _,callpoint = pcall(function() error("",4) end)&lt;br /&gt;				print(string.format(msg,string.gsub(callpoint,"(^w%*%.%w*%:%d+)","%1")))&lt;br /&gt;				o[k] = v&lt;br /&gt;				return o[k]&lt;br /&gt;			end&lt;br /&gt;		})&lt;br /&gt;	elseif(type(o) == "function") then&lt;br /&gt;		return function(...)&lt;br /&gt;			local _,callpoint = pcall(function() error("",4) end)&lt;br /&gt;			print(string.format(msg,string.gsub(callpoint,"(^w%*%.%w*%:%d+)","%1")))&lt;br /&gt;			return o(unpack(arg))&lt;br /&gt;		end&lt;br /&gt;	end&lt;br /&gt;end&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Example Usage:&lt;br /&gt;&lt;code&gt;Ace = {}&lt;br /&gt;&lt;br /&gt;function Ace:print(msg)&lt;br /&gt;	print(msg)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;function foo()&lt;br /&gt;	print("FOO!")&lt;br /&gt;end&lt;br /&gt;ace = deprecate(Ace,"ace","Ace")&lt;br /&gt;FOO = deprecate(foo,"FOO","foo")&lt;br /&gt;&lt;br /&gt;FOO()&lt;br /&gt;ace:print("moo")&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Output of Example Usage:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;./deprecate.lua:38: Warning, deprecated feature 'FOO' in use.  Use 'foo' instead.&lt;br /&gt;FOO!&lt;br /&gt;./deprecate.lua:39: Warning, deprecated feature 'ace' in use.  Use 'Ace' instead.&lt;br /&gt;moo&lt;/code&gt;</description>
      <pubDate>Tue, 06 Dec 2005 03:39:23 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/943</guid>
      <author>kergoth (Chris Larson)</author>
    </item>
    <item>
      <title>Lua: Lazy Map Implementation: Round One</title>
      <link>http://snippets.dzone.com/posts/show/942</link>
      <description>Concept code for a lazy map implementation in Lua&lt;br /&gt;&lt;br /&gt;&lt;code&gt;require "std.table" -- For memoize&lt;br /&gt;&lt;br /&gt;function map(t, f)&lt;br /&gt;    local nt = table.memoize(function (k) return f(t[k]) end)&lt;br /&gt;    local mt = getmetatable(nt)&lt;br /&gt;    function mt:__pairs()&lt;br /&gt;        local k&lt;br /&gt;        local function mynext()&lt;br /&gt;            k,v = next(t, k)&lt;br /&gt;            if k == nil then return nil end&lt;br /&gt;            return k,nt[k]&lt;br /&gt;        end&lt;br /&gt;        return mynext, self&lt;br /&gt;    end&lt;br /&gt;    return nt&lt;br /&gt;end&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Example Usage:&lt;br /&gt;&lt;code&gt;require "std.base" -- For better table tostring()&lt;br /&gt;&lt;br /&gt;local mylist = {1,3,5,7,9}&lt;br /&gt;local newlist = map(mylist, function(v) return 3 * v - 2 end)&lt;br /&gt;assert(mylist[3] == 5)&lt;br /&gt;assert(newlist[3] == 13)&lt;br /&gt;&lt;br /&gt;require "std.base" -- For the pairs() that obeys the __pairs metamethod&lt;br /&gt;print("old:", mylist)&lt;br /&gt;print("new(3*v-2):", newlist)&lt;/code&gt;</description>
      <pubDate>Mon, 05 Dec 2005 16:13:24 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/942</guid>
      <author>kergoth (Chris Larson)</author>
    </item>
    <item>
      <title>Lua: Sane Granular Defaults for User Supplied Data</title>
      <link>http://snippets.dzone.com/posts/show/941</link>
      <description>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.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;local mooDB&lt;br /&gt;&lt;br /&gt;local defaults = {&lt;br /&gt;    a = {&lt;br /&gt;        foo = "bar"&lt;br /&gt;    },&lt;br /&gt;    b = 1,&lt;br /&gt;    c = {&lt;br /&gt;        bar = "foo"&lt;br /&gt;    },&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if not mooDB then&lt;br /&gt;    -- NOTE: This would not be in the actual real world code.  This&lt;br /&gt;    -- simulates user data, normally loaded from some sort&lt;br /&gt;    -- of datastore, which is SavedVariables in the case of&lt;br /&gt;    -- World of Warcraft.&lt;br /&gt;    mooDB = {&lt;br /&gt;        c = {&lt;br /&gt;            bop = "whee"&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;function inheritdefaults(t, defaults)&lt;br /&gt;    for k,v in pairs(defaults) do&lt;br /&gt;        if t[k] then&lt;br /&gt;            if type(v) == "table" then&lt;br /&gt;                inheritdefaults(t[k], v)&lt;br /&gt;            end&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    local mt = getmetatable(t) or {}&lt;br /&gt;    function mt:__index(k)&lt;br /&gt;        return defaults[k]&lt;br /&gt;    end&lt;br /&gt;    return setmetatable(t, mt)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;inheritdefaults(mooDB, defaults)&lt;br /&gt;&lt;br /&gt;assert(mooDB ~= defaults)&lt;br /&gt;assert(mooDB.a == defaults.a)&lt;br /&gt;assert(mooDB.c ~= defaults.c)&lt;br /&gt;assert(mooDB.a.foo == "bar")&lt;br /&gt;assert(mooDB.b == 1)&lt;br /&gt;assert(mooDB.c.bar == "foo")&lt;br /&gt;assert(mooDB.c.bop == "whee")&lt;/code&gt;</description>
      <pubDate>Mon, 05 Dec 2005 16:05:04 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/941</guid>
      <author>kergoth (Chris Larson)</author>
    </item>
    <item>
      <title>Lua: Descending Table Traversal Round 2: Iterator Object</title>
      <link>http://snippets.dzone.com/posts/show/940</link>
      <description>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.&lt;br /&gt;&lt;br /&gt;Code:&lt;br /&gt;&lt;code&gt;traverse = {}&lt;br /&gt;function traverse:new(tname)&lt;br /&gt;	local o = {}&lt;br /&gt;	o.names = {}&lt;br /&gt;	o.queue = {}&lt;br /&gt;	o.cur = {&lt;br /&gt;		tbl = nil,&lt;br /&gt;		path = nil,&lt;br /&gt;		state = nil,&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	local mt = {}&lt;br /&gt;	function mt:__call(tn)&lt;br /&gt;		return o:iter(tn)&lt;br /&gt;	end&lt;br /&gt;	mt.__index = self&lt;br /&gt;	setmetatable(o, mt)&lt;br /&gt;&lt;br /&gt;	if tname then&lt;br /&gt;		o:enqueue(tname)&lt;br /&gt;	end&lt;br /&gt;	return o&lt;br /&gt;end&lt;br /&gt;function traverse:next()&lt;br /&gt;	local v&lt;br /&gt;	local names, queue, cur = self.names, self.queue, self.cur&lt;br /&gt;&lt;br /&gt;	local function _poptbl()&lt;br /&gt;		if cur.tbl then&lt;br /&gt;			names[cur.tbl] = nil&lt;br /&gt;		end&lt;br /&gt;		cur.tbl = table.remove(queue, 1)&lt;br /&gt;		cur.path = names[cur.tbl]&lt;br /&gt;		cur.state = nil&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	repeat&lt;br /&gt;		-- Find something to return to the user...&lt;br /&gt;		if not cur.state then&lt;br /&gt;			-- Pop a new table off the stack&lt;br /&gt;			_poptbl()&lt;br /&gt;			if not cur.tbl then&lt;br /&gt;				-- No more tables to process&lt;br /&gt;				return nil&lt;br /&gt;			end&lt;br /&gt;		end&lt;br /&gt;		cur.state,v = next(cur.tbl, cur.state)&lt;br /&gt;	until cur.state&lt;br /&gt;&lt;br /&gt;	if type(v) == "table" then&lt;br /&gt;		local path = cur.path.."."..cur.state&lt;br /&gt;		names[v] = path&lt;br /&gt;		table.insert(queue, v)&lt;br /&gt;	end&lt;br /&gt;	return cur.path,cur.tbl,cur.state,v&lt;br /&gt;end&lt;br /&gt;function traverse:iter(tname)&lt;br /&gt;	if tname then&lt;br /&gt;		self:enqueue(tname)&lt;br /&gt;	end&lt;br /&gt;	return function(...) return self:next(unpack(arg)) end, nil, nil&lt;br /&gt;end&lt;br /&gt;function traverse:enqueue(tname)&lt;br /&gt;	local v = _G[tname]&lt;br /&gt;	table.insert(self.queue, v)&lt;br /&gt;	self.names[v] = tname&lt;br /&gt;end&lt;br /&gt;function traverse:reset()&lt;br /&gt;	self.names = {}&lt;br /&gt;	self.queue = {}&lt;br /&gt;end&lt;br /&gt;local traverse_mt = {&lt;br /&gt;    __call = function(self, tname)&lt;br /&gt;             	if tname then&lt;br /&gt;             		return self:new(tname):iter()&lt;br /&gt;             	else&lt;br /&gt;             		return self:new()&lt;br /&gt;             	end&lt;br /&gt;             end&lt;br /&gt;}&lt;br /&gt;setmetatable(traverse, traverse_mt)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Example Usage:&lt;br /&gt;&lt;code&gt;foo = {a={},b={},c={"bar"},d={e={},f={"moo"}},1,2,3,4,5}&lt;br /&gt;bar = {"alpha", "beta", "theta", omega = {}}&lt;br /&gt;&lt;br /&gt;local mytraverser = traverse()&lt;br /&gt;mytraverser:enqueue("bar")&lt;br /&gt;mytraverser:enqueue("foo")&lt;br /&gt;for p,t,k,v in mytraverser() do&lt;br /&gt;--for p,t,k,v in traverse('foo') do&lt;br /&gt;	print(string.format("%s[%s] = %s",tostring(p),tostring(k),tostring(v)))&lt;br /&gt;end&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Output from Example Usage:&lt;br /&gt;&lt;code&gt;bar[1] = alpha&lt;br /&gt;bar[2] = beta&lt;br /&gt;bar[3] = theta&lt;br /&gt;bar[omega] = table: 0x510650&lt;br /&gt;foo[1] = 1&lt;br /&gt;foo[2] = 2&lt;br /&gt;foo[3] = 3&lt;br /&gt;foo[4] = 4&lt;br /&gt;foo[5] = 5&lt;br /&gt;foo[a] = table: 0x5102d0&lt;br /&gt;foo[c] = table: 0x510370&lt;br /&gt;foo[b] = table: 0x510320&lt;br /&gt;foo[d] = table: 0x5103c0&lt;br /&gt;foo.c[1] = bar&lt;br /&gt;foo.d[e] = table: 0x5104c0&lt;br /&gt;foo.d[f] = table: 0x510510&lt;br /&gt;foo.d.f[1] = moo&lt;/code&gt;</description>
      <pubDate>Mon, 05 Dec 2005 13:27:31 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/940</guid>
      <author>kergoth (Chris Larson)</author>
    </item>
  </channel>
</rss>
