* * * * * Notes about a Lua lint checker > Luacheck is a static analyzer and a linter for Lua [1]. Luacheck detects > various issues such as usage of undefined global variables, unused > variables and values, accessing uninitialized variables, unreachable code > and more. > “Luacheck [2]” The one real issue I have with Lua [3] is its dynamic typing [4]. Of all the bugs I fix in my own Lua code, I would say that the majority are due to typos (wrong variable name) or an unexpected type. So I was quite happy to come across and try out Luacheck. And fortunately, it's pretty straightforward to run [5]. I ran it over “Project: Sippy- Cup [6]” and … wow. The extensive regression test I have has already flushed out the typos and the unexpected type errors I tend to make. But Luacheck found quite a few unused variables (which is nice—it also found a bunch of unsused LPeg [7] expressions) and a ton of unintentional global variables (because I forgot to declare them with local). The output is easy to read (here's a representative sample from some non- work related code I have): > Checking ptest-cr-select.lua **Failure** > > ptest-cr-select.lua:53:9: variable **amount** was previously defined as an argument on line 52 > ptest-cr-select.lua:128:9: variable **okay** is never accessed > ptest-cr-select.lua:193:40: unused argument **event** > ptest-cr-select.lua:197:43: shadowing upvalue **conn** on line 194 > ptest-cr-select.lua:213:21: shadowing upvalue **argument** event on line 193 > ptest-cr-select.lua:215:15: unused variable **rem** > ptest-cr-select.lua:215:15: shadowing upvalue **rem** on line 194 > > Total: **7** warnings / **0** errors in 1 file > About the only false positive it finds is this idiom: > function foo(param1,param2) > local param1 = param1 or "default value" > local param2 = param2 or 3 > local a = ... > -- ... > end > where it will flag param1 and param2 as shadowing an upvalue. This idiom though, is used to provide a default value if a parameter isn't given to a function. It's easy enough to fix, either: > function foo(param1,param2) > param1 = param1 or "default value" > param2 = param2 or 3 > local a = ... > -- ... > end > or > function foo(param1,param2) > local param1 = param1 or "default value" -- luacheck: ignore > local param2 = param2 or 3 -- luacheck: ignore > local a = ... > -- ... > end > Overall, I'm glad I found this tool. It's been a real eye opener. [1] http://www.lua.org/ [2] https://github.com/mpeterv/luacheck [3] http://www.lua.org/ [4] gopher://gopher.conman.org/0Phlog:2008/01/11.1 [5] http://luacheck.readthedocs.org/ [6] gopher://gopher.conman.org/0Phlog:2014/03/05.1 [7] http://www.inf.puc-/ Email Sean Conner at sean@conman.org .