Page 2 of 3

Re: Share your Utils

Posted: Sat Feb 26, 2011 4:33 pm
by tentus
Noticed that I'm using this a fair bit nowadays, so I thought I'd share.

Code: Select all

-- returns the next string in a list of strings.
-- "current" is a string. "list" is a table of strings.
function nextInList(current, list)
	for i=1, #list do
		if current == list[i] then
			if i == #list then
				return list[1]
			else
				return list[i + 1]
			end
		end
	end
	return current
end

Re: Share your Utils

Posted: Sat Feb 26, 2011 11:16 pm
by BlackBulletIV
May as well dump Grace's data utilities here:

Code: Select all

--[[
    Swaps the current item between a and b. If current
    is equal to a, then b will be returned, and vice
    versa.
    
    -- Parameters --
    current:mixed
    The current value.
    
    a:mixed
    The first possible value.
    
    b:mixed
    The second possible value.
    
    -- Returns --
    mixed
    If current == a, returns b. If current == b, returns a.
--]]
function Grace.swap(current, a, b)
    if current == a then
        return b
    else
        return a
    end
end

--[[
    Randomly chooses one of the parameters given.
    
    -- Parameters --
    ...:mixed
    One or more values to choose from.
    
    -- Returns --
    One of those values.
--]]
function Grace.choose(...)
    return arg[math.random(1, arg.n)]
end

--[[
    Copies (shallow) an object. If the object is a table
    it will create a new table and set each key and value
    from the object to the new table. It will also set the
    metatable to be the same.
    
    -- Parameters --
    object:mixed
    
    -- Returns --
    The copied object.
--]]
function Grace.copy(object)
    if type(object) ~= "table" then
        return object
    end
    
    local new = {}
    for k, v in pairs(object) do
        new[k] = v
    end
    
    return setmetatable(new, getmetatable(object))
end

--[[
    Deeply copies an object. Works the same way as copy() except
    that it recursively copies every key and value. It does the
    same for the metatable.
    
    -- Parameters --
    object:mixed
    
    -- Returns --
    The deeply copied object.
--]]
function Grace.deepCopy(object)
    local lookup = {}
    
    local function copy(obj)
        if type(obj) ~= "table" then
            return obj
        elseif lookup[obj] then
            return lookup[obj]
        end

        local new = {}
        lookup[obj] = new
        for k, v in pairs(obj) do
            new[copy(k)] = copy(v)
        end
        
        return setmetatable(new, copy(getmetatable(obj)))
    end
    
    return copy(object)
end

Re: Share your Utils

Posted: Sun Feb 27, 2011 9:48 am
by bartbes
Some stuff in there is just horrible.

Code: Select all

--[[
function Grace.swap(current, a, b)
    return current == a and b or a
end --ternary ftw

function Grace.choose(...)
    return select(math.random(1, select("#", ...), ...)
    --or at the very least put it in a table yourself and use
    --the # operator, this is lua 5.1
end

Re: Share your Utils

Posted: Sun Feb 27, 2011 8:30 pm
by BlackBulletIV
Why is not using a ternary statement horrible? Does the same thing, but I do admit the ternary looks nicer.

I don't see what's bad about using arg and arg.n; are they going to be removed from the language or something? It's not like my code is any longer, to the contrary.

Finally, I'm reading the 5.0 Programming in Lua, and converting from ActionScript.

Re: Share your Utils

Posted: Sun Feb 27, 2011 8:39 pm
by bartbes
Yes, arg and especially table.n are deprecated and should not be used.

Re: Share your Utils

Posted: Sun Feb 27, 2011 8:44 pm
by slime
arg (and arg.n and tbl.n and table.getn and all that stuff) was deprecated 6 years ago. It probably won't work. As bartbes pointed out, a second way to write a more correct version would be something like

Code: Select all

function Grace.choose(...)
	if not ... then return end
	local tbl = {...}
	return tbl[math.random(#tbl)]
end

Re: Share your Utils

Posted: Sun Feb 27, 2011 9:11 pm
by BlackBulletIV
slime wrote:deprecated 6 years ago.
Oh, well that explains. I'll have to convert some code now, lol.
slime wrote:It probably won't work.
Funny thing is, it actually does work.

Re: Share your Utils

Posted: Mon Feb 28, 2011 9:49 am
by Robin
BlackBulletIV wrote:
slime wrote:It probably won't work.
Funny thing is, it actually does work.
The subtle difference between "you shouldn't use it" and "you can't use it". ;)
slime wrote:a second way to write a more correct version would be something like

Code: Select all

function Grace.choose(...)
	if not ... then return end
	local tbl = {...}
	return tbl[math.random(#tbl)]
end
The problem is that doesn't work:

Code: Select all

function isempty(...)
    if not ... then
        print "empty"
    else
        print "not empty"
    end
end
isempty() --> empty
isempty(1) --> not empty
isempty(false) --> empty
isempty(false, true) --> empty
So every sequence starting with a false value is considered empty. A way to make it work would be:

Code: Select all

function Grace.choose(...)
	if select('#', ...) == 0 then return end
	local tbl = {...}
	return tbl[math.random(#tbl)]
end

Re: Share your Utils

Posted: Mon Feb 28, 2011 9:52 am
by slime
My bad. I can never get away from the select function! :o

Re: Share your Utils

Posted: Mon Feb 28, 2011 9:56 am
by Robin
slime wrote:My bad. I can never get away from the select function! :o
You could, actually, do without select(), I just realised.

Code: Select all

function Grace.choose(...)
   local tbl = {...}
   if #tbl == 0 then return end
   return tbl[math.random(#tbl)]
end
or even:

Code: Select all

function Grace.choose(...)
   local tbl = {...}
   return #tbl > 0 and tbl[math.random(#tbl)] or nil
end