Development/Programming Standards
From Norganna's AddOns
RFC: This article is currently under a Request For Comments. This means that the article is regarding a proposed addition or improvement and exact design details may be changed. It is requested that users with input regarding the module use the talk page of the article to discuss possible design changes.
In an effort to standardize code and to maintain code readability, the team follows a set of guidelines when writing code. These guidelines are confirmed to be followed during Code Reviews. Violations of these standards qualify as a Minor Defect during the code review process, with defect code "Not conforming to standards." All Developers should remember these standards while developing and attempt to conform to them whenever possible. In the event that a standard cannot be followed, it can be ignored (preferably with comments indicating justification), but the issue should also be brought up to a Core Developer to re-evaluate the standard so it can be rewritten without exceptions.
Minimize Variable Scope
Variables should always be declared as close to the implementation as possible. This reduces the amount of work spent trying to determine the origin of the variable in question. Variables should also be reduced to the lowest level block possible for their purpose. This ensures the garbage collector can do its job efficiently, ensures that variables are protected from rogue code in other areas, and is overall simply cleaner.As a corollary to this standard, always use locals whenever possible. Globals should be minimized at all costs due to their inefficiency, their potential to be overrun by other addons, and for maintainability.
Prefer:
function foo()
-- Long sequence of code
local a = 1;
bar(a);
end
Instead of:
function foo()
local a;
-- Long sequence of code
a = 1;
bar(a);
end
Prefer:
function foo(i)
if i > 5 then
local n = 1;
for x = 2, i do
n = n * x;
end
return n;
else
local n = 0;
for x = 1, i do
n = n + x;
end
return n;
end
end
Instead Of:
function foo(i)
local n;
if i > 5 then
n = 1;
for x = 2, i do
n = n * x;
end
else
n = 0;
for x = 1, i do
n = n + x;
end
end
return n;
end
Variable Naming
Constant Variables
Any code that contains constants should be declared as such. Containing magic numbers within code is detrimental to maintainability, so all constants should contain descriptive names about what those values represent, instead of hard-coding the numbers. This allows for (1) future developers to more quickly identify what the constant is supposed to represent, and (2) easy modification in the event the value needs to change in the future. Even values which are expected to never change (such as the number of seconds in a minute) should be pulled to a constant to allow for distinction between it and other similar values (such as the number of minutes in an hour).Constants should always be in ALL_CAPS using underscores to represent spaces between words. Constants should always be locals following the convention specified earlier if not needed outside of the file in which they are declared, or in the module's table if they should be accessible elsewhere.
Avoid:
function numDays(secs) return secs / 86400 end
Better:
local SECONDS_IN_DAY = 24 * 60 * 60; function numDays(secs) return secs / SECONDS_IN_DAY; end
Best:
local HOURS_IN_DAY = 24 local MINUTES_IN_HOUR = 60; local SECONDS_IN_MINUTE = 60; local SECONDS_IN_DAY = HOURS_IN_DAY * MINUTES_IN_HOUR * SECONDS_IN_MINUTE; function numDays(secs) return secs / SECONDS_IN_DAY; end
Code Tabulation
All blocks should be tabulated in the normal fashion. Any code block (such as if...end, do...end, while...end, etc.) should have its contents tabbed out one indentation. Indentation form is not standardized, though spaces are preferred for consistency across editors.Lines which continue on multiple lines should have their additional lines tabbed out an additional mark from the first line. In the event that this is being done due to a large parameter list, parameters and parenthesis pairs should be columnar-aligned.
Example:
function foo()
if a == b then
bar("Hello world",
a,
b,
1
);
baz();
else
bar(c, d);
end
end

