Node with Lua bindings? Luvit!

I have recently discovered the excellent “The Changelog” Podcast and a couple of weeks ago there was an interview with Tim Caswell that most people probably know from NodeJS fame. However, on this interview he wasn’t talking about NodeJS, instead about his new project Luvit – Lua + libUV + jIT (GitHub project page).

Having played around a tiny bit with Lua, I decided to give Luvit a go. As with my previous foray into Lua, it was great fun.

Installation of Luvit was straightforward on my Linux box and within a few minutes I was ready to go.

As Luvit is pretty new, there isn’t a great deal of documentation beyond a simple “Hello World” app, but “Hello World” apps aren’t enough to really get your teeth into. The only idea my ever- degenerating brain could come up with at such short notice was a simple bookmark saver, so apologies for the lack of imagination.

local http = require("http")
local url = require("url")
local string  = require("string")
 
function split(str, sep)
   local sep, fields = sep or ":", {}
   local pattern = string.format("([^%s%%s]+)", sep)
   string.gsub(str, pattern, function(c) fields[#fields+1] = c end)
   return fields
end
 
http.createServer(
   function (req, res)
      local entry, tags, body = {}, {}, ""
 
      -- get and parse the query string
      local parse_url = url.parse(req["url"], true)
      local query = parse_url.query
 
      -- if a url has been supplied, save it and any associated tags
      if query['u'] then
	 if query["t"] then
	    tags = split(query["t"], ",")
	 end
	 entry["url"] = query["u"]
	 entry["tags"] = tags
 
	 -- output to console
	 print "-= Saving =-"
	 print("url: ",entry.url)
	 for i,v in pairs(entry.tags) do print("tag: ",v) end
 
	 -- body of the returned output
	 body = "URL: "..query["u"].." saved."
      else
	 body = "To bookmark a URL simply pass u and t in the query string"
      end
 
      res:writeHead(200, {
		       ["Content-Type"] = "text/plain",
		       ["Content-Length"] = #body
		    })
      res:finish(body)
   end):listen(8080)
 
print("Server listening at http://localhost:8080/")

The above doesn’t do much apart from store a passed URL and it’s tags into a Lua Table.

For example:

URL: http://localhost:8080/
Response: To bookmark a URL simply pass u and t in the query string
Action: Does nothing.

URL: http://localhost:8080/?u=http://www.robsearles.com&t=test,blog
Response: URL: http://www.robsearles.com saved.
Action: Saves a table called entry

{
url: http://www.robsearles.com,
entry: { test, blog }
}

Whilst the code above is very simple, it did allow me to get more of a feel for both the language and the framework (if that is the right word) rather than mindlessly copying and pasting.

The only thing that threw me was that Lua doesn’t have a native split string function, unlike PHP, Python, Ruby etc, instead you have to roll your own as described in this wiki page.

In conclusion, yet again I really enjoyed delving into Lua – it really is something I would like to play around with more. Luvit looks like a great project, especially as Tim was saying on the podcast that it is benchmarking faster and has a lower memory footprint than NodeJS.

Luvit is definitely something to keep an eye on.