2020-02-10 My first steps with Lua

Well, the title of this post is a misnomer – I am already well past my first steps with Lua, since I’ve written a few (admittedly, very simple) Lua scripts. In the near future, though, I’d like to play around with Lua a tad more seriously. (I still do not have a lot of spare time for that, but we’ll see how it goes.)

One thing I missed when I tried Lua last time (it could have been a year or so ago) was a feature found in Node.JS’s npm package manager. In Node, you can describe all the packages you need for your applications/script/whatever and run npm install to have them installed in a local node_modules directory. While this is not necessarily optimal with respect to the disk usage, it is very convenient – every app can be pretty much self-contained. When I researched Lua, it seemed to me that you cannot do a similar thing with Lua “rocks” (which is a cool name btw) – you just have to install them globally (per system or per user).

Well, apparently I was wrong. It seems that it is possible to make Lua behave like Node and install modules under the current directory, and it was already possible to do that almost four years ago. The trick to do that (since it is a trick, this is not something Luarocks can do by default) is described here.

Since reading is one thing and learning is another, let us apply the method from that guide to install a Lua module locally. I decided to use Lua-CSV for that. (Spoiler alert: it wasn’t as simple as I wished.)

I started with creating an empty directory and installing it there using Luarocks:

cd /tmp
rm -rf lua-csv-test
mkdir lua-csv-test
cd lua-csv-test
luarocks install --tree lua_modules lua-csv

Then, following the howto, I created the set-paths.lua file:

local version = _VERSION:match("%d+%.%d+")
print(version)
package.path = 'lua_modules/share/lua/' .. version .. '/?.lua;lua_modules/share/lua/' .. version .. '/?/init.lua;' .. package.path
package.cpath = 'lua_modules/lib/lua/' .. version .. '/?.so;' .. package.cpath

Finally, let us create the script which is going to actually use the Lua-CSV module. (Of course, I am going to utilize the example script from the README for that.)

local csv = require("lua-csv.csv")
local f = csv.open("file.csv")
for fields in f:lines() do
  for i, v in ipairs(fields) do print(i, v) end
end

The tricky part here was the call to require. It turns out that require("lua-csv") wouldn’t work, as it would try to find the file ./lua_modules/share/lua/5.3/lua-csv.lua, and the luarocks install command installed the module as ./lua_modules/share/lua/5.3/lua-csv/csv.lua. Frankly, I have no idea how to predict where the module file will land after installing other than inspecting the lua_modules directory. (I told you these are my first steps with Lua!).

To top it off, we need the csv file itself:

Letter,Number
A,65
B,66

And now, I can say lua -l set-paths lua-csv-test.lua, and it Just Works™!

All I can say is that this is way more complicated than just npm install module followed by const module = require('module'), but that won’t discourage me. In the next installment (some day!), I am going to use Lua to process my Org agenda in csv format.

CategoryEnglish, CategoryBlog, CategoryLua