I never really got a hang of using the Lua ecosystem to do practical programming.
A big hinderence often is the “no batteries” included nature of Lua, which by design has a very small core.
Lua has LuaRocks - The Lua package manager, which has plenty of packages to many practical things. Here I’m trying to sit down and “map the territody” using familiar set of tasks that I often do with Python
I installed luarocks using
nix, which is my current driver –
nix-env -i luarocks. I could have easily used
brew install luarocks. The luarocks.org site has a search box to find packages that are registered with lua, but packages can be installed from elsewhere also.
I started with a simple markdown package:
➜ ~ luarocks install --local markdown Installing https://luarocks.org/markdown-0.33-1.src.rock markdown 0.33-1 depends on lua >= 5.1, < 5.4 (5.1-1 provided by VM) No existing manifest. Attempting to rebuild... markdown 0.33-1 is now installed in /Users/pgowda/.luarocks (license: MIT/X11)
Note: if you don’t specify
--local flag, luarocks will try to install it in “system” location – something I’d gladly avoid.
I then tried to use it from Lua REPL (I already had installed Lua):
$ lua Lua 5.4.3 Copyright (C) 1994-2021 Lua.org, PUC-Rio > local md = require("markdown") stdin:1: module 'markdown' not found: no field package.preload['markdown'] no file './share/lua/5.4/markdown.lua' no file './markdown.lua' no file './markdown/init.lua' no file './lib/lua/5.4/markdown.so' no file './markdown.so' no file './lib/lua/5.4/loadall.so' stack traceback: [C]: in function 'require' stdin:1: in main chunk [C]: in ? >
The issue above is that unlike Python (
site-packages location, which is nice, but is its own can of worms), lua doesn’t know about luarocks location.
You can inform the REPL to look for files there by adding this line:
$ lua Lua 5.4.3 Copyright (C) 1994-2021 Lua.org, PUC-Rio > package.path = package.path .. ';/Users/pgowda/.luarocks/share/lua/5.1/?.lua' > local markdown = require('markdown') > markdown("Hello, *world*") <p>Hello, <em>world</em></p>
So, now we have the package available for programming.
Interestingly, when I imported the
markdown package like this, I ran into issues:
local md = require 'markdown' > md("Hello, *world*") stdin:1: global 'md' is not callable (a nil value) stack traceback: stdin:1: in main chunk [C]: in ?
So, this means the local name of the package should match the original name of the package. I’m sure, I’ve tripped up against this couple of times and not realize what was happening.
markdown.lua module1 exports the
markdown function as a global:
-- For compatibility, set markdown function as a global _G.markdown = markdown
Rest of the module (see 1 for source), is a good study in how to structure a module as a standalone script. This behaviour is very similar to how Python treats a module as a standalone script via the user of