Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lua test and assign inside loop control

Tags:

lua

luasql

Is there / please suggest a syntax to achieve a compact 'test and assign' in lua?

Consider this segment from luasql examples ( http://keplerproject.org/luasql/examples.html )

-- retrieve a cursor
cur = assert (con:execute"SELECT name, email from people")
-- print all rows, the rows will be indexed by field names
row = cur:fetch ({}, "a")
while row do
  print(string.format("Name: %s, E-mail: %s", row.name, row.email))
  -- reusing the table of results
  row = cur:fetch (row, "a")
end

I am learning lua, and really struggling to accept the duplicated call to cur:fetch(). I see that repeat/until trivially fixes the issue, but then it seems I have to test twice:

repeat
  row = cur:fetch ({}, "a")
  if row then
    print ...
  end
until nil == row

I consider this less error prone for the case of 'row = ...' getting more complex, but still seems inelegant.

like image 406
robm Avatar asked May 09 '26 04:05

robm


1 Answers

You can simplify the first loop to this:

local row = {}
while row do
  row = cur:fetch(row, "a")
end

EDIT: The sample page hits at a possible solution using iterators and a for loop, like @doukremt is suggesting. Unfortunately it also contains a couple errors (it assumes that the rows get "unpacked" in the second example but not in the first, does not declare everything local, and omits more parenthesis than it's sane to in a sample code). Here's how you can transform a cursor in an iterator:

local iterate = function(cur)
  return function() return cur:fetch() end
end

Here's how you use it:

local cur = assert(con:execute("SELECT name, email from people"))

for row in iterate(cur) do
  print(string.format ("%s: %s", row.name, row.email))
end

I must warn you that iterators are in general more expensive than while/repeat loops. Execute performance tests if you are worried about speed.

like image 51
kikito Avatar answered May 11 '26 23:05

kikito



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!