Difference between revisions of "Lua code style guidelines"
(→Spaces) |
(→Misc) |
||
Line 270: | Line 270: | ||
end | end | ||
</source> | </source> | ||
+ | ''Comment: WTF ... nil evaluating to false on boolean comparison doesn't mean they're equal.'' | ||
Bad: | Bad: | ||
<source lang="lua"> | <source lang="lua"> | ||
Line 276: | Line 277: | ||
* Don't use unnecessary parenthesis unless they improve readability a lot. | * Don't use unnecessary parenthesis unless they improve readability a lot. | ||
− | + | ||
− | + | v------------------------------------------------------------------------------------------------ | |
Paranthesis always improve readability a lot | Paranthesis always improve readability a lot | ||
− | ^ | + | ^------------------------------------------------------------------------------------------------ |
<source lang="lua"> | <source lang="lua"> |
Revision as of 17:45, 15 August 2014
These are only guidelines for more readable code, in some (rare) cases they may result in less readable code and should not be followed.
hh############################################################# hh#############################################################
DRAFT TO BE DISCUSSED!)
hh############################################################# hh#############################################################
Comments
Unspecific definition potentially resulting in shitload of discussions v------------------------------------------------------------------------------------------------
- Write comments to describe why something is done, or why it is done in a particular way. Don't write comments that describe things that are obvious from the code.
- Good:
width = width - 2 -- Adjust for 1px border on each side
- Bad:
width = width - 2 -- Decrement width by two
^------------------------------------------------------------------------------------------------
- Comments should follow English grammar rules, this means starting with a capital letter, using commas and apostrophes where appropriate, and ending with a period. The period may be omitted in single-sentence comments. If the first word of a comment is an identifier it's casing should not be changed.
-- This is a properly formatted comment.
-- This isnt. (Missing apostrophe)
-- neither is this. (Lowercase first letter)
- Comments should have a space between the comment characters and the first word.
--This is wrong.
- Inline comments should be separated from the code by two spaces.
foo() -- A proper comment
Missing multiline comment definition
v------------------------------------------------------------------------------------------------ ^------------------------------------------------------------------------------------------------
Why not doxygen?
v------------------------------------------------------------------------------------------------
- If you write comments for a documentation generation tool, write the comments in LuaDoc format.
^------------------------------------------------------------------------------------------------
Lines, spaces, and indentation
- Indentation is done with one tab per indentation level. Tabs are considered to have eight space width.
- Lines are wrapped at 80 characters where possible, with an upper limit of 90.
Continuation lines
- Conditionals have following lines indented by two tabs:
if long_function_call(with, many, arguments) and
another_function_call() then
do_something()
end
- Function arguments are indented by two tabs:
foo(bar, biz, "This is a long string..."
baz, qux, "Lua")
- Function definition continuations are also indented by two tabs.
function foo(a, b, c, d,
e, f, g, h)
...
end
- When breaking around a binary operator you should break after the operator.
foo["bar"]["biz"]["baz"] =
"Example"
if a or b or c or d or
e or f then
foo()
end
Empty lines
- Use a single empty line to separate sections of long functions.
Why not use something more visible as a line of ---?
v------------------------------------------------------------------------------------------------
- Use two empty lines to separate top-level functions and large tables.
^------------------------------------------------------------------------------------------------
- Do not use a empty line after conditional or looping opening statements.
Good:
function foo()
if x then
bar()
end
end
Bad:
function foo()
if x then
bar()
end
end
- Don't leave white-space at the end of lines.
Spaces
- Spaces are not used around parenthesis, brackets, or curly braces.
Good:
foo({baz=true})
bar[1] = "Hello world"
Inconsistent example at beginning there's shown to use spaces around binary operators (as told some lines below!!!)
v------------------------------------------------------------------------------------------------ ^------------------------------------------------------------------------------------------------
Bad:
foo ( { baz=true } )
bar [ 1 ]
- Spaces are used after, but not before, commas and semicolons.
Good:
foo(a, b, {c, d})
Bad:
foo(a,b,{c , d})
Why can they be omitted? It's hard to read without them any other code uses them for what reason allow it here?
v------------------------------------------------------------------------------------------------
- Spaces are used around binary operators. With the exception of the member access operator :::(".") where there shouldn't be spaces, and the concatenation operator ("..") where spaces are optional. In short one-line table definitions the spaces around the equals sign can be omitted.
^------------------------------------------------------------------------------------------------
Good:
local num = 2 * (3 / 4)
foo({bar=true})
foo({bar = true})
local def = {
foo = true,
bar = false,
}
Bad:
local num=2*(3/4)
local def={
foo=true,
bar=false,
}
Way to unspecific and potential source of lots of discussions ... what's ok 5 spaces 10 15?
v------------------------------------------------------------------------------------------------
- * Use spaces to align related things, but don't go overboard:
- Good:
local node_up = minetest.get_node(pos_up)
local node_down = minetest.get_node(pos_down)
- Bad:
local x = true
local very_long_variable_name = false
local foobar = true
local unrelated = {}
^------------------------------------------------------------------------------------------------
Tables
- Small tables may be placed on one line. Large tables have one entry per line, with the opening and closing braces on lines without items. In large tables the final element has a trailing comma.
Good:
local foo = {bar=true}
foo = {
bar = 0,
biz = 1,
baz = 2,
}
Bad:
foo = {bar = 0,
biz = 1,
baz = 2}
foo = {
bar = 0, biz = 1,
baz = 2
}
- In list-style tables where each element is short multiple elements may be placed on each line.
local first_eight_letters = {
"a", "b", "c", "d",
"e", "f", "g", "h",
}
Naming
- Functions and variables should be named in
lowercase_underscore_style
. The exception is class-like functions, egPseudoRandom()
, which use UpperCamelCase.
- Avoid inventing compound words; filename is O.K., but getbox and collisiondetection are not.
- Avoid leading and/or trailing underscores. They're ugly and can be hard to see.
Misc
- Multiple statements on the same line are discouraged.
Bad:
foo(); bar()
- You can put conditionals/loops with small conditions and bodies on one line, although this is discouraged for all but the smallest ones.
Good:
local f, err = io.open(filename, "r")
if not f then return err end
if a then return a
elseif b then return b
elseif c then return c
end
Bad:
if not f and use_error then error(err) elseif not f then return err end
- Don't compare values explicitly to true, false, or nil, unless it's really needed.
Good:
local f, err = io.open(filename, "r")
if not f then return err end
local t = {"a", true, false}
for i = 1, 5 do
if t[i] == nil then -- Needs an explicit nil check to avoid triggering on false.
t[i] = "Default"
end
end
Comment: WTF ... nil evaluating to false on boolean comparison doesn't mean they're equal. Bad:
if f == nil then return err end
- Don't use unnecessary parenthesis unless they improve readability a lot.
v------------------------------------------------------------------------------------------------
Paranthesis always improve readability a lot
^------------------------------------------------------------------------------------------------
if y then bar() end -- Good
if (not x) then foo() end -- Bad
- Write function definitions of the form
function foo()
instead of the lambda formfoo = function()
, except when putting functions in tables, where the second should be used.
- Avoid globals. The only globals that you should create are namespace tables.
- Don't let functions get too large. Maximum length depends on complexity; simple functions can be longer than complex functions.
- Minetest core is Lua API 5.1 don't even think about using LuaJIT or Lua 5.2 functions in core!