lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> > 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,
    __add = function(t, s)
      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>