• Subject: Re: Lua string
• From: Luis Carvalho <carvalho@...>
• Date: Thu, 26 Apr 2007 12:32:30 -0400

> > I have not yet seen an implementation that is acceptable to The Lua
> > Way, so for now I live with the limitation and program around it by
> > using table.concat() when necessary.
>
> If you are willing to be a little more verbose, you can write this,
> with some metatable magic:
>
> 	local s=String""
> 	for i=0,30000 do
> 		s=s..i
> 	end
> 	print(s:value())

Like this:

-- String.lua
local setmetatable = setmetatable
local ipairs = ipairs
local tostring = tostring
local concat = table.concat
local sub = string.sub
local wrap = coroutine.wrap
local yield = coroutine.yield

module "String"

local letters = function(t)
return wrap(function()
for i, v in ipairs(t) do
v = tostring(v)
for j = 1, #v do
yield(sub(v, j, j))
end
end
end)
end

local compare = function(t1, t2)
local next1, next2 = letters(t1), letters(t2)
local l1, l2 = next1(), next2()
while l1 and l2 and l1 == l2 do
l1, l2 = next1(), next2()
end
return l1 == l2
end

function new(t)
local t = t or {}
local intern = ""
local last = 0
return setmetatable(t, {
__tostring = function(t, k)
if last < #t then
intern = intern .. concat(t, "", last + 1)
last = #t
end
return intern
end,
t[#t + 1] = s
return t
end,
__eq = compare
})
end

Test:

\$ lua -lString
Lua 5.1.1  Copyright (C) 1994-2006 Lua.org, PUC-Rio
> s1 = String.new{'a', 'bc', 'def'}
> s2 = String.new{'abc', 'd'}
> = s1
abcdef
> = s2
abcd
> = s1 == s2
false
> s2 = s2 + 'ef'
> return  s1 == s2
true

Benchmark:

\$ time lua -e 'local s=""; local c="vary long number..."; for i=0,30000 do s = s..i; if s==c then end end'

real    0m4.320s
user    0m2.168s
sys     0m2.130s

\$ time lua -e 'require"String"; local s=String.new(); local c=String.new{"vary long number..."}; for i=0,30000 do s = s+i; if s==c then end end'

real    0m0.294s
user    0m0.288s
sys     0m0.006s

Cheers,
Luis.

--
A mathematician is a device for turning coffee into theorems.
-- P. Erdos

--
Luis Carvalho
Applied Math PhD Student - Brown University
PGP Key: E820854A <carvalho@dam.brown.edu>