Code Convention - GammaStation/Gamma-Station GitHub Wiki
Введение
Code Convention - свод несложных правил по оформлению кода. Его наличие подразумевает, что все кто вносят свои изменения, с ним соглашаются и руководствуются им в полной мере. Обязательно прочтите всю статью, если зашли сюда в первый раз. Это очень важно.
В случае если что-то не было здесь оговорено, вы можете уточнить этот момент в конфе. Хотя скорее всего это значит, что в том, что вас интересует вы вольны думать самостоятельно.
Пробелы и отступы
Блоки кода
В качестве отступов для компилируемых блоков кода используются только табы. Если код относится к комментарию (то есть для примера), то выравнивать рекомендуется пробелами.
Процедуры и функции
Между вызовом процедуры/функции и скобками не должно быть пробела.
Плохо:
/proc/foo()
return function (1)
Хорошо:
/proc/foo()
return function(1)
Дабы было проще искать упоминания этой функции поиском.
Операторы управления (if, while, for и т.д.)
Не должны писаться одной строкой. Иногда, если так действительно будет лучше, допускается однострочные switch
и else if
конструкции.
Плохо:
if(something) return TRUE
for(var/i in something) i.foo()
Хорошо:
if(something)
return TRUE
for(var/i in something)
i.foo()
Допустимо:
switch(x)
if(case_1) foo()
if(case_2) return FALSE
Все остальные операторы (+, -, =, &&, || и т.д.)
Один пробел перед оператором и один пробел после. Исключение - побитовые. Пробелы при их использовании вставляйте на своё усмотрение.
Плохо:
var/a=1
var/b = 2
var/c =a+b
Хорошо:
var/a = 1
var/b = 2
var/c = a + b
Скобки и запятые
Следуйте единому формату. Так или иначе пробел после запятой - обязателен.
Плохо:
list( 1,2, 3, 4 ,5)
Хорошо:
list(1, 2, 3, 4, 5)
Допустимо:
list( 1 , 2 , 3 , 4 , 5 )
Комментарии
Форматирование только через пробелы. Обратите внимание на выравнивание.
Плохо:
#define A "something" // Это что-то.
#define B "anything" //Это что угодно.
Хорошо:
#define A "something" // Это что-то.
#define B "anything" // Это что угодно.
Выравнивание новых строк
Например, при объявлении элементов списка - преимущественно пробелами.
Плохо:
list(1, 2, 3,
4, 5, 6)
Хорошо:
list(1, 2, 3
4, 5, 6)
Допустимо:
list(
1, 2, 3,
4, 5, 6
)
Описание путей
Абсолютные
Все пути в обязательном порядке должны быть абсолютными.
Плохо:
obj
var
varname1 = 0
varname2
proc
proc_name()
code
item
weapon
name = "Weapon"
proc
proc_name2()
..()
code
Хорошо:
/obj
var/varname1 = 0
var/varname2
/obj/proc/proc_name()
code
/obj/item/weapon
name = "Weapon"
/obj/item/weapon/proc/proc_name2()
..()
code
Должны начинаться с /
Плохо:
mob/living
Хорошо:
/mob/living
Так как, путь не начинающийся со слэша компилятором будет считаться как относительный, и если где-либо будет путь /foo/mob/living, он может присвоить все переменные класса /mob/living(который мы написали без слэша), классу соответствующему этому пути.
Не описываются через текстовую строку
Плохо:
var/path = "/obj/item/something"
Хорошо:
var/path = /obj/item/something
Пути не описываются через текстовую строку, в связи с тем, что при компиляции, компилятор не обратит внимание на несуществующий путь в текстовой строке, и не выдаст ошибку. У этого могут быть последствия, в случае, если классы будут удаляться, или их путь будет меняться, можно просто забыть поменять его во всех местах.
Работа с кодом
К прочтению:
- [Работа с чатом]
- [Работа с реалтайм событиями]
Объявление аргументов в процедурах
Не должно быть конструкций типа var/
и as ...
Плохо:
/proc/foo(var/atom/A as area|turf|obj|mob)
Хорошо:
/proc/foo(atom/A)
:
Оператор Использование запрещено. Всегда приводите объект к нужному вам типу.
Плохо:
/proc/foo(atom/A)
return A:some_var
Хорошо:
/proc/foo(atom/A)
var/obj/O = A
return O.some_var
Ведь данный оператор запускает поиск по всем переменным и сверяется, есть ли такая переменная вообще у интересующего нас пути.
Магические числа
Если не знаете что это, то прочитайте эту статью Магическое число (программирование). Соответственно их быть не должно. Используйте дефайны или константные переменные.
Плохо:
/proc/foo(variable)
switch(variable)
if(1)
do something
if(2)
return
Хорошо:
#define CASE_1 1
#define CASE_2 2
/proc/foo(variable)
switch(variable)
if(CASE_1)
do something
if(CASE_2)
return
#undef CASE_1
#undef CASE_2
Булевский тип
Вместо 1 и 0 используйте TRUE
и FALSE
соответственно.
src
Использование Используйте только тогда, когда это необходимо.
Плохо:
/mob/some/class/proc/foo()
src.some_var = some_value
src.another_var = another_value
Хорошо:
/mob/some/class/proc/foo()
some_var = some_value
another_var = another_value
Пример необходимого использования:
/mob/some/class/proc/foo(some_var, another_var)
src.some_var = some_var
src.another_var = another_var
Особенности BYOND
spawn()
Использование Не используйте. О причинах читайте тут [Работа с реалтайм событиями].
Работа с циклами (black magic)
Цикл вида for(var/i = 1; i <= const_val; i++)
должен быть записан в следующей форме for(var/i in 1 to const_val)
. Причина: второй цикл работает быстрее. Почему? Хороший вопрос, стоит задать его кодерам BYOND. У обоих видов одинаковое поведение, но у второго есть нюансы. to
тоже самое, что и <=
, соответственно чтобы было <
нужно сделать for(var/i in 1 to const_val - 1)
. Ещё важный момент - const_val
переменная не должна быть изменена во время цикла. То есть если вы делаете проход по списку, который изменяется внутри цикла, а const_val
размер списка, то вам нужно использовать классический, первый, вариант.