• Subject: Re: Question
• From: Philippe Lhoste <PhiLho@...>
• Date: Tue, 30 Oct 2001 11:51:04 +0100 (MET)

```Volkan Civelek wrote:
>>>
This is my first email and fyi i am very new born in Lua.

Now the question is;

why does the below code gives me

"error: bad argument #1 to `write' (string expected, got nil)
stack traceback:
1:  function `write' [C]
2:  main of file `ask.lua' at line 10

Error: Script failed"

this???

--case.lua

function foo (rt, from, s)
for i=1,10 do
tinsert (rt, from, strsub(s,i,i+1))
end
end
local combi = {}
local var1 = {"1234567890"}
foo(combi, 34, var1[1])
write (combi[34], "\n")
write (combi[35], "\n")  --this guy has a problem

--EOF

and combi[34] writes 0 ??
<<<

Welcome to Lua, I hope you will enjoy your discovery of this wonderful
little language.
I am still a newbie myself (although I am beginning to grasp some concepts),
that's why I enjoy taking a look at other people's code... :-)

Stepping mentally on your code (good exercice), I can say that you first
insert 12, 23, ..., 90, 0 at position 34, each value pushing to higher position
the previous one (insert operation). That's why you got a '0' at position 34
(no other digit after it, so it is a single character).

Now, I dumped the table, using Jon Kleiser's asText function (Peter, your
function uses the tadd function, but we don't have it...).
It shows that tinsert seems to overwrite the previous value, instead of
pushing the values.
That's why you got nil on combi[35].
Now, I am confused. Is it a bug in tinsert? (I remember a discussion on this
function, I can't recall if it is related, or just on the "n" value.)

The official (from the manual) algorithm for tinsert is:

function tinsert (t, ...)
local pos, value
local n = getn(t)
if arg.n == 1 then
pos, value = n+1, arg[1]
else
pos, value = arg[1], arg[2]
end
t.n = n+1;
for i=n,pos,-1 do
t[i+1] = t[i]
end
t[pos] = value
end

Now, we can see where the problem is:
the "for i=n,pos,-1 do" loop is never run because pos > n (the first getn
returns 0). So we always end up to "t[pos] = value", ie. we overwrite the
previous value.
Perhaps it is on purpose?

A way to get the result you expect is to rewrite the tinsert function as
follow:

function tinsert (t, ...)
local pos, value
local n = getn(t)
if arg.n == 1 then
pos, value = n+1, arg[1]
else
pos, value = arg[1], arg[2]
end
if pos <= n then
t.n = n+1;
for i=n,pos,-1 do
t[i+1] = t[i]
end
else
t.n = pos
end
t[pos] = value
end

ie. if we are inserting a value at a position higher than the current
"size", it becomes the new size. Works at least with your code, I didn't tested it
thoroughly....

PS.: Since it is useful, I put here a copy of asText, as I copied from this
mailing list. I don't know if there is an improved version. Works fine with
simple tables (those I use :-).

--# From: kleiser@online.no (Jon Kleiser)

function asText(obj)
-- Returns a textual representation of "any" Lua object,
-- incl. tables (and nested tables).
-- Functions are not decompiled (of course).
-- Try: print(asText({{"a", "b"}; c=3}))

visitRef = {}
visitRef.n = 0

asTxRecur = function(obj, asIndex)
if type(obj) == "table" then
if visitRef[obj] then
return "@"..visitRef[obj]
end
visitRef.n = visitRef.n +1
visitRef[obj] = visitRef.n

local begBrac, endBrac
if asIndex then
begBrac, endBrac = "[{", "}]"
else
begBrac, endBrac = "{", "}"
end
local t = begBrac
local k, v = nil, nil
repeat
k, v = next(obj, k)
if k ~= nil then
if t > begBrac then
t = t..", "
end
t = t..asTxRecur(k, 1).."="..asTxRecur(v)
end
until k == nil
return t..endBrac
else
if asIndex then
-- we're on the left side of an "="
if type(obj) == "string" then
return obj
else
return "["..obj.."]"
end
else
-- we're on the right side of an "="
if type(obj) == "string" then
return '"'..obj..'"'
else
end
end
end
end -- asTxRecur

return asTxRecur(obj)
end -- asText

I keep it in a file, and when I need it, I put a dofile("_AsText_.lua") at
the beginning of the program, and use it as "print(asText(combi))".

PPS.: Suggestion: use subject lines more explicit than "Question", since
most of the primary posting here are such questions, this make hard to browse
the archives:-)
I would rename it, say... "Problem with tinsert" or "Problem with write", or
something like that.

Regards.

--
--=#=--=#=--=#=--=#=--=#=--=#=--=#=--=#=--=#=--
Philippe Lhoste (Paris -- France)
Professional programmer and amateur artist
http://jove.prohosting.com/~philho/
--=#=--=#=--=#=--=#=--=#=--=#=--=#=--=#=--=#=--

Sent through GMX FreeMail - http://www.gmx.net

```