lua-users home
lua-l archive

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


Friends, Ali Rezvani and Hugo, thanks for your suggestions - they
forced me to experiment further!

Difficulty was that unlike with example of logs, I need not just print
nils, but need to mimic the behavior of io.read which returns them to
caller.

I found solution, though it has some curious hack inside - it seems ok
to insert nils into table by index for example, but the table size
should be preallocated
to work properly.

The following example demonstrates it - "res" variable collects values
as if they are read from user - if there is unparsable number, it
inserts nil.
It works all right if "res" is pre-populated with something to proper
length, but if the corresponding line is removed all following entries
are "nil", i.e. it prints

bla nil mla

when working properly, but if the line is removed or commented, it yields

bla nil nil

```
t = {'bla', 'hm', 'mla'}

ioread = function(...)
  local args = table.pack(...)
  local res = {}
  for i, v in ipairs(args) do res[i] = 0 end -- try removing or
commenting out this line
  for i, v in ipairs(args) do
    x = t[i]
    if v == '*n' then x = tonumber(x) end
    res[i] = x
  end
  return table.unpack(res)
end

x,y,z = ioread('*l', '*n', '*l')
print(x, y, z)
```
sincerely yours,
Rodion

On Tue, Nov 7, 2023 at 9:30 AM rzvxa <rzvxa@protonmail.com> wrote:
>
> Hey Rodion,
>
> If I'm not mistaken problem isn't from table.insert or table.pack, ipairs doesn't iterate over nil items at the end of the table since you can write something like this to remove an element from the table:
> ```lua
> local t = {}
> t[1] = 'something'
> t[1] = nil
> ```
> To be honest I'm not sure about elements in the middle of the array for example whether this is true or not(but if I had to guess I would say yes it is true):
> ```lua
> local t = {}
> t[1] = "x"
> t[2] = "y"
> t[3] = "z"
> t[2] = nil
> asserteq(#t, 2)
> ```
> I wrote a logger a few months ago and had the same problem since I wanted to log the nil inputs so here is what it did:
> ```lua
> function log.dump(...)
>     local args = {...}
>     -- select will get an accurate count of array len, counting trailing nils
>     local len = select('#', ...)
>     for i = 1,len do
>         args[i] = pprint.pformat(args[i], nil)
>         args[i] = args[i] .. '\n'
>     end
>     log.log('dump', '1;32', table.unpack(args))
> end
>
> ```
> Try using `select` to access your table length if the table contains nil values. Let me know if this little snippet helped you in achieving your goal.
>
> Kind Regards,
> Ali Rezvani
>
> ------- Original Message -------
> On Tuesday, November 7th, 2023 at 7:26 AM, Родион Горковенко <rodiongork@gmail.com> wrote:
>
>
> > Hi Friends!
> >
> > Regard the case - I'm redefining io.read(...) - for example to allow
> > 3-rd party code run in web-page (with Lua compiled to JS), requesting
> > user to provide input data via pop-ups. To properly mock the original
> > function behavior, I would like it to return "nil" sometimes (say upon
> > reading number when
> > no digits were provided).
> >
> > io.read = function(...)
> > res = {}
> > for _, typ in ipairs(table.pack(...)) do
> > val = someCodeWhichCallsPrompt()
> > if typ == '*n' then val = parseNumberWhimsically(val) end
> > table.insert(res, val)
> > end
> > return table.unpack(res)
> > end
> >
> > The difficulty is that if "parseNumberWhimsically" may return "nil",
> > it won't be inserted into the table. I don't know whether "table.pack"
> > users some complicated magic for this or on contrary I'm missing
> > something obvious. Thanks in advance for any hints!
> >
> > sincerely yours,
> > Rodion