Getting more familiar with Lua
Created:
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.
The 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 2 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 __main__
.