Making Lua Like Php |
|
Note: Some of these PHP-style functions don't do exactly the same as PHP. In some cases this is intentional.
Based on [PHP print_r]. Based on code by Nick Gammon, hacked by DracoBlue to fit to [PHP print_r]-Style.
Example: print_r{ 5,3,{5,3} } -->
[1] => 5
[2] => 3
[3] => Table
{
[1] => 5
[2] => 3
}
Compatibility: Lua 5.0 and 5.1
function print_r (t, indent, done) done = done or {} indent = indent or '' local nextIndent -- Storage for next indentation value for key, value in pairs (t) do if type (value) == "table" and not done [value] then nextIndent = nextIndent or (indent .. string.rep(' ',string.len(tostring (key))+2)) -- Shortcut conditional allocation done [value] = true print (indent .. "[" .. tostring (key) .. "] => Table {"); print (nextIndent .. "{"); print_r (value, nextIndent .. string.rep(' ',2), done) print (nextIndent .. "}"); else print (indent .. "[" .. tostring (key) .. "] => " .. tostring (value).."") end end end function print_r (t, indent) -- alt version, abuse to http://richard.warburton.it local indent=indent or '' for key,value in pairs(t) do io.write(indent,'[',tostring(key),']') if type(value)=="table" then io.write(':\n') print_r(value,indent..'\t') else io.write(' = ',tostring(value),'\n') end end end -- alt version2, handles cycles, functions, booleans, etc -- - abuse to http://richard.warburton.it -- output almost identical to print(table.show(t)) below. function print_r (t, name, indent) local tableList = {} function table_r (t, name, indent, full) local serial=string.len(full) == 0 and name or type(name)~="number" and '["'..tostring(name)..'"]' or '['..name..']' io.write(indent,serial,' = ') if type(t) == "table" then if tableList[t] ~= nil then io.write('{}; -- ',tableList[t],' (self reference)\n') else tableList[t]=full..serial if next(t) then -- Table not empty io.write('{\n') for key,value in pairs(t) do table_r(value,key,indent..'\t',full..serial) end io.write(indent,'};\n') else io.write('{};\n') end end else io.write(type(t)~="number" and type(t)~="boolean" and '"'..tostring(t)..'"' or tostring(t),';\n') end end table_r(t,name or '__unnamed__',indent or '','') end
See Also: LuaRecipes - Recursive table print/serialization
Sorry for the length!
--[[ Author: Julio Manuel Fernandez-Diaz Date: January 12, 2007 (For Lua 5.1) Modified slightly by RiciLake to avoid the unnecessary table traversal in tablecount() Formats tables with cycles recursively to any depth. The output is returned as a string. References to other tables are shown as values. Self references are indicated. The string returned is "Lua code", which can be procesed (in the case in which indent is composed by spaces or "--"). Userdata and function keys and values are shown as strings, which logically are exactly not equivalent to the original code. This routine can serve for pretty formating tables with proper indentations, apart from printing them: print(table.show(t, "t")) -- a typical use Heavily based on "Saving tables with cycles", PIL2, p. 113. Arguments: t is the table. name is the name of the table (optional) indent is a first indentation (optional). --]] function table.show(t, name, indent) local cart -- a container local autoref -- for self references --[[ counts the number of elements in a table local function tablecount(t) local n = 0 for _, _ in pairs(t) do n = n+1 end return n end ]] -- (RiciLake) returns true if the table is empty local function isemptytable(t) return next(t) == nil end local function basicSerialize (o) local so = tostring(o) if type(o) == "function" then local info = debug.getinfo(o, "S") -- info.name is nil because o is not a calling level if info.what == "C" then return string.format("%q", so .. ", C function") else -- the information is defined through lines return string.format("%q", so .. ", defined in (" .. info.linedefined .. "-" .. info.lastlinedefined .. ")" .. info.source) end elseif type(o) == "number" then return so else return string.format("%q", so) end end local function addtocart (value, name, indent, saved, field) indent = indent or "" saved = saved or {} field = field or name cart = cart .. indent .. field if type(value) ~= "table" then cart = cart .. " = " .. basicSerialize(value) .. ";\n" else if saved[value] then cart = cart .. " = {}; -- " .. saved[value] .. " (self reference)\n" autoref = autoref .. name .. " = " .. saved[value] .. ";\n" else saved[value] = name --if tablecount(value) == 0 then if isemptytable(value) then cart = cart .. " = {};\n" else cart = cart .. " = {\n" for k, v in pairs(value) do k = basicSerialize(k) local fname = string.format("%s[%s]", name, k) field = string.format("[%s]", k) -- three spaces between levels addtocart(v, fname, indent .. " ", saved, field) end cart = cart .. indent .. "};\n" end end end end name = name or "__unnamed__" if type(t) ~= "table" then return name .. " = " .. basicSerialize(t) end cart, autoref = "", "" addtocart(t, name, indent) return cart .. autoref end
A test:
----------------------------------------------------------- --- testing table.show t = {1, {2, 3, 4}, default = {"a", "b", d = {12, "w"}, e = 14}} t.g = t.default print("-----------------------------------") print(table.show(t)) -- shows __unnamed__ table tt = {1, h = {["p-q"] = "a", b = "e", c = {color = 3, name = "abc"}}, 2} f = table.show tt[f] = "OK" print("-----------------------------------") print(table.show(tt, "tt", "--oo-- ")) -- shows some initial 'indent' t.m = {} t.g.a = {} t.g.a.c = t t.tt = tt.new t.show = table.show print("-----------------------------------") print(table.show(t, "t")) -- most typical use print("-----------------------------------") print(table.show(math.tan, "tan")) -- not a table is OK print("-----------------------------------") s = "a string" print(table.show(s, "s")) -- not a table is OK
The output:
-----------------------------------
__unnamed__ = {
[1] = 1;
[2] = {
[1] = 2;
[2] = 3;
[3] = 4;
};
["default"] = {
[1] = "a";
[2] = "b";
["e"] = 14;
["d"] = {
[1] = 12;
[2] = "w";
};
};
["g"] = {}; -- __unnamed__["default"] (self reference)
};
__unnamed__["g"] = __unnamed__["default"];
-----------------------------------
--oo-- tt = {
--oo-- [1] = 1;
--oo-- [2] = 2;
--oo-- ["function: 0x8070e20, defined in (28-99)@newprint_r.lua"] = "OK";
--oo-- ["h"] = {
--oo-- ["b"] = "e";
--oo-- ["c"] = {
--oo-- ["color"] = 3;
--oo-- ["name"] = "abc";
--oo-- };
--oo-- ["p-q"] = "a";
--oo-- };
--oo-- };
-----------------------------------
t = {
[1] = 1;
[2] = {
[1] = 2;
[2] = 3;
[3] = 4;
};
["m"] = {};
["show"] = "function: 0x8070e20, defined in (28-99)@newprint_r.lua";
["g"] = {
[1] = "a";
[2] = "b";
["e"] = 14;
["d"] = {
[1] = 12;
[2] = "w";
};
["a"] = {
["c"] = {}; -- t (self reference)
};
};
["default"] = {}; -- t["g"] (self reference)
};
t["g"]["a"]["c"] = t;
t["default"] = t["g"];
-----------------------------------
tan = "function: 0x806f758, C function"
-----------------------------------
s = "a string"
Example: explode(" and ","one and two and three and four") --> {"one","two","three","four"}
Compatibility: Lua 5.0 and 5.1 -- By RichardWarburton
function explode(div,str) if (div=='') then return false end local pos,arr = 0,{} -- for each divider found for st,sp in function() return string.find(str,div,pos,true) end do table.insert(arr,string.sub(str,pos,st-1)) -- Attach chars left of current divider pos = sp + 1 -- Jump past current divider end table.insert(arr,string.sub(str,pos)) -- Attach chars right of last divider return arr end
Use table.concat:
PHP implode(join,array) is equivalent to Lua table.concat(table,join)
PHP: implode(" ",array("this","is","a","test","array")) --> "this is a test array"
Lua: table.concat({"this","is","a","test","array"}," ") --> "this is a test array"
function phpTable(...) -- abuse to: http://richard.warburton.it local newTable,keys,values={},{},{} newTable.pairs=function(self) -- pairs iterator local count=0 return function() count=count+1 return keys[count],values[keys[count]] end end setmetatable(newTable,{ __newindex=function(self,key,value) if not self[key] then table.insert(keys,key) elseif value==nil then -- Handle item delete local count=1 while keys[count]~=key do count = count + 1 end table.remove(keys,count) end values[key]=value -- replace/create end, __index=function(self,key) return values[key] end }) for x=1,table.getn(arg) do for k,v in pairs(arg[x]) do newTable[k]=v end end return newTable end
Example Usage:
-- arguments optional test = phpTable({blue="blue"},{red="r"},{green="g"}) test['life']='bling' test['alpha']='blong' test['zeta']='blast' test['gamma']='blue' test['yak']='orange' test['zeta']=nil -- delete zeta for k,v in test:pairs() do print(k,v) end
The output:
blue blue red r green g life bling alpha blong gamma blue yak orange
Example: preg_replace("\\((.*?)\\)","", " Obvious exits: n(closed) w(open) rift")
The following preg_replace variants support using the wildcards %n in the replace.
1. Using Lua-style regular expressions:
function preg_replace(pat,with,p) return (string.gsub(p,pat,with)) end
2. Using PCRE or POSIX regular expressions:
function preg_replace(pat,with,p) return (rex.gsub(p,pat,with)) end
table_print)