Здравствуйте, T4r4sB, Вы писали:
Н>> Да и вообще в раздувании по вертикали проблем не вижу.
TB>Не раздражает, когда короткая мысль не помещается в экран?
У тебя мышка без колёсика? Да и короткая мысль поместится на экран при любом форматировании
Здравствуйте, Shmj, Вы писали: S>Вот, по умолчанию в той же Idea — около 75 символов. По сути это газетная строка или близко к ней. S>А ведь можно было сделать длинным? Ну хотя бы 150-200 символов. И читать код как книгу. Тем более мониторы то расширяются. S>Не пробовали? Что лучше? Сколько символов ставите?
А вы код только пишете и читаете, или все-таки иногда отлаживаете и запускаете?
У меня стоит дефолт 100 символов. Но такая ширина используется в основном только для заголовков методов со строковыми параметрами и текстовыми строками.
Там где код, обычно длина не более 40-60 символов.
я отлаживаю код.
1. В длинные выражения в одну строку не поставить точку останова, не зайти отладчиком.
Ну или это если у кого вдруг это отладчик позволяет, то неудобно.
2. Промежуточные вычисления я часто сохраняю в локальные переменные, чтобы можно было посмотреть отладчиком . Это не качается тривиальных, но длинных выражений.
Код в результате оказывается внезапно короче, потому что присвоенное в 1 месте переменная используется вместо повторяющихся в одном методе цепочек.
3. Короткий строки кода лучше мерджится гитом в случае, если правили одно место, и легче руками разрешаются конфликты.
4. В Коротких строках легче находить повторения и выносить в отдельные методы.
В коде я допускаю не больше 3-4 уровней вложенности (циклов, блоков if и т.п ), за счет этого он получается не широкий, больше уровней необходимо выносить в отдельные методы.
Вот пример кода другого разработчика который я недавно переформатировал. Какой из вариантов готов к дальнейшему расширению?
Было
procedure TRestKModelTerminals.Add(const aVertex: Integer; aValues: TStringArray; var aData: ARColumn;
const aInfo: RKModelInfo; const aInput: TRestInput);
var
modelState: TKModel2State;
island: RIsland;
rowIndex: Integer;
value: String;
values: TStringArray;
terminal: RTerminal;
terminalInfo: RTerminalInfo;
column: Integer;
uri: TURI;
begin
modelState := aInfo.Model.LastModel;
island := modelState.Islands.Islands[modelState.IslandNumByVertex(aVertex)];
terminalInfo := modelState.Graph.GetTerminalInfo(aVertex);
for column := 0 to length(aValues) - 1 do
begin
case column of
0 {vertex}: value := aVertex.ToString();
1 {terminal}: value := modelState.Graph.TerminalByVertex(aVertex).index.ToString();
2 {key}: value := terminalInfo.key;
3 {island}: value := terminalInfo.Island.ToString();
4 {isUnderVoltage}: value := BoolToStr(island.UnderVoltage, AInput.ContentType);
5 {state}: value := '';
6 {checkPoint}: value := '';
7 {updateTime}: value := TimeToStr(island.TmStUpdate);
8 {oppositeTerminals}: value := 'Opposite terminals';
end;
aValues[column] := value;
end;
rowIndex := aData.AddRow(aValues);
for column := 0 to length(aValues) - 1 do
begin
case column of
8 {oppositeTerminals}:
begin
uri := GetUrlHead(TableUseHttps);
uri.Path := joinStr(['documents', AInput.DocUID.ToString(), 'kmodel-terminals'],'/');
uri.AddParameter('oppositeFor', aVertex.ToString);
aData.Links [column, rowIndex] := TIdURI.URLEncode (URI.ToString);
end;
end;
end;
if AInput.ContentType = ctForm then
addIcon(aData, rowIndex, aInfo, modelState.Graph.TerminalByVertex(aVertex));
end;
function TRestKModelTerminals.Get(const AInput: TRestInput): ARColumn;
var
model: TKModel2State;
info: RKModelInfo;
fieldsId: TIntArray;
data: ARColumn;
values: TStringArray;
vertex: Integer;
params: RKModelParams;
terminal: RTerminal;
terminalInfo: RTerminalInfo;
edges, nodeEdges: RSEdges;
island: RIsland;
i, j: Integer;
stat: TServiceStat;
begin
Result.Clear;
model := CurrentModel(AInput).LastModel;
if not Assigned(model) then exit;
info := CurrentModelInfo(AInput);
// TMonitor.Enter(model);try
stat := TServiceStat.Create('');
stat.Start();
data.Clear;
fieldsId := Fields_.FindFields(AInput.fields);
if AInput.ContentType <> ctForm then
begin
fieldsId.DeleteValue(8);
end;
// Det := AInput.Detailing;
// if AInput.fields.Count = 0 then begin
// case Det of
// tdLow : SetLength(fa, 7);
// tdMedium: SetLength(fa, 9);
// end;
// end;
values := Fields_.ColumnsText.PickByNumber(fieldsId);
data.ColumnsText(values);
Fields_.AssignFieldsProps(data);
PrepareParams (AInput, params);
if params.OppositeFor >= 0 then
begin
edges := model.Graph.SGraph.edgesFrom(params.OppositeFor);
for i := 0 to edges.Count - 1 do
if model.Graph.TerminalByVertex(edges[i].ToVertex).id >= 0 then
Add(edges[i].ToVertex, values, data, info, AInput);
edges.Free();
end
else
if params.ConnectedFor >= 0 then
begin
edges := model.Graph.SGraph.edgesFrom(params.ConnectedFor);
for i := 0 to edges.Count - 1 do
begin
if model.Graph.TerminalByVertex(edges[i].ToVertex).id < 0 then
begin
nodeEdges := model.Graph.SGraph.edgesFrom(edges[i].ToVertex);
for j := 0 to nodeEdges.Count - 1 do
if nodeEdges[j].ToVertex <> params.ConnectedFor then
Add(nodeEdges[j].ToVertex, values, data, info, AInput);
nodeEdges.Free();
end;
end;
edges.Free();
end
else
if params.Vertex >= 0 then
begin
edges := model.Graph.SGraph.edgesFrom(params.Vertex);
for i := 0 to edges.Count - 1 do
Add(edges[i].ToVertex, values, data, info, AInput);
end
else
for vertex := 0 to model.Graph.SGraph.VerticesCount - 1 do
begin
terminal := model.Graph.TerminalByVertex(vertex);
terminalInfo := model.Graph.GetTerminalInfo(vertex);
island := model.Islands.Islands[model.IslandNumByVertex(vertex)];
if terminal.id < 0 then continue;
if (params.IslandIndex >= 0) and (terminalInfo.Island <> params.IslandIndex) then continue;
if island.TmStUpdate < params.StartTime then continue;
Add(vertex, values, data, info, AInput);
end;
finally
stat.Stop();
FStat.SummStat(stat);
// TMonitor.Exit(model);
Result := data;
end;
end;
Стало
type
RRowContext = record
model: TKModel2State;
ModelState: TKModel2State;
Vertex: Integer;
Values: TStringArray;
aData: ARColumn;
Info: RKModelInfo;
AInput: TRestInput;
procedure Clear;
end;
function TRestKModelTerminals.GetValue(index: Integer; const RC: RRowContext;
const Island: RIsland; const terminalInfo: RTerminalInfo): string;
begin
case index of
0 {vertex}: Result := RC.Vertex.ToString;
1 {terminal}: Result := RC.modelState.Graph.TerminalByVertex(RC.Vertex).index.ToString;
2 {key}: Result := terminalInfo.key;
3 {island}: Result := terminalInfo.Island.ToString;
4 {isUnderVoltage}: Result := BoolToStr(island.UnderVoltage, RC.AInput.ContentType);
5 {state}: Result := '';
6 {checkPoint}: Result := '';
7 {updateTime}: Result := {TimeToStr} DateToISO8601(island.TmStUpdate);
8 {oppositeTerminals}: Result := 'Opposite terminals';
else
Assert (false);
end;
end;
procedure TRestKModelTerminals.Add(const RC: RRowContext);
var
island: RIsland;
rowIndex: Integer;
terminalInfo: RTerminalInfo;
c: Integer;
uri: TURI;
begin
island := RC.modelState.Islands.Islands[RC.modelState.IslandNumByVertex(RC.Vertex)];
terminalInfo := RC.modelState.Graph.GetTerminalInfo(RC.Vertex);
for c := 0 to length(RC.Values) - 1 do
RC.Values[c] := GetValue(c, RC, Island, terminalInfo);
rowIndex := RC.aData.AddRow(RC.Values);
c := RC.aData.FindColumn('oppositeTerminals');
if c >= 0 then begin{oppositeTerminals}
uri := GetUrlHead(TableUseHttps);
uri.Path := joinStr(['documents', RC.AInput.DocUID.ToString, 'kmodel-terminals'],'/');
uri.AddParameter('oppositeFor', RC.Vertex.ToString);
RC.aData.Links [c, rowIndex] := TIdURI.URLEncode (URI.ToString);
end;
if RC.AInput.ContentType = ctForm then
addIcon(RC.aData, rowIndex, RC.Info, RC.modelState.Graph.TerminalByVertex(RC.Vertex));
end;
procedure TRestKModelTerminals.Get_OppositeFor (var RC: RRowContext; aFromT: integer);
var
edges: RSEdges;
i, v: Integer;
G: TKModelGraph;
begin
G := RC.model.Graph;
edges := G.SGraph.edgesFrom(aFromT);
for i := 0 to edges.Count - 1 do begin
v := edges[i].ToVertex;
if G.TerminalByVertex(v).id < 0 then continue;
RC.Vertex := v;
Add(RC);
end;
edges.Free;
end;
procedure TRestKModelTerminals.Get_ConnectorFor (var RC: RRowContext; aFromT: integer);
var
edges, nodeEdges: RSEdges;
i, j, nv, v: Integer;
G: TKModelGraph;
begin
G := RC.model.Graph;
edges := G.SGraph.edgesFrom(aFromT);
for i := 0 to edges.Count - 1 do begin
v := edges[i].ToVertex;
if G.TerminalByVertex(v).id >= 0 then continue;
nodeEdges := G.SGraph.edgesFrom(v);
for j := 0 to nodeEdges.Count - 1 do begin
nv := nodeEdges[j].ToVertex;
if nv = aFromT then continue;
RC.Vertex := nv;
Add(RC);
end;
nodeEdges.Free;
end;
edges.Free;
end;
procedure TRestKModelTerminals.Get_Vertex (var RC: RRowContext; aFromT: integer);
var
edges: RSEdges;
i, v: Integer;
begin
edges := RC.model.Graph.SGraph.edgesFrom(aFromT);
for i := 0 to edges.Count - 1 do begin
RC.Vertex := edges[i].ToVertex;
Add(RC);
end;
end;
procedure TRestKModelTerminals.Get_All (var RC: RRowContext; aIslandIndex: integer);
var
v: Integer;
terminal: RTerminal;
terminalInfo: RTerminalInfo;
island: RIsland;
params: RKModelParams;
G: TKModelGraph;
begin
G := RC.model.Graph;
PrepareParams (RC.AInput, params);
for v := 0 to G.SGraph.VerticesCount - 1 do begin
terminal := G.TerminalByVertex(v);
terminalInfo := G.GetTerminalInfo(v);
island := RC.model.Islands.Islands[RC.model.IslandNumByVertex(v)];
if terminal.id < 0 then continue;
if (aIslandIndex >= 0) and (terminalInfo.Island <> params.IslandIndex) then continue;
if island.TmStUpdate < params.StartTime then continue;
RC.Vertex := v;
Add(RC);
end;
end;
function TRestKModelTerminals.Get(AInput: TRestInput): ARColumn;
var
RC: RRowContext;
KModel: TKModel2;
fieldsId: TIntArray;
params: RKModelParams;
stat: TServiceStat;
begin
Result.Clear;
RC.Clear;
KModel := CurrentModel(AInput);
if KModel = nil then exit;
RC.model := KModel.LastModel;
if not Assigned(RC.model) then exit;
RC.info := KModelServerData.ModelInfoByModel(KModel);
RC.modelState := RC.Info.Model.LastModel;
try
stat := TServiceStat.Create('');
stat.Start;
RC.Adata.Clear;
RC.AInput := AInput;
fieldsId := Fields_.FindFields(AInput.fields);
if AInput.ContentType <> ctForm then
fieldsId.DeleteValue(8);
RC.values := Fields_.ColumnsText.PickByNumber(fieldsId);
RC.Adata.ColumnsText(RC.Values);
Fields_.AssignFieldsProps(RC.Adata);
PrepareParams (AInput, params);
if params.OppositeFor >= 0 then
Get_OppositeFor (RC, params.OppositeFor)
else if params.ConnectedFor >= 0 then
Get_ConnectorFor (RC, params.ConnectedFor)
else if params.Vertex >= 0 then
Get_Vertex (RC, params.Vertex)
else
Get_All (RC, params.IslandIndex);
finally
stat.Stop;
FStat.SummStat(stat);
Result := RC.Adata;
end;
end;
Здравствуйте, Shmj, Вы писали:
S>Вот, по умолчанию в той же Idea — около 75 символов. По сути это газетная строка или близко к ней.
S>А ведь можно было сделать длинным? Ну хотя бы 150-200 символов. И читать код как книгу. Тем более мониторы то расширяются.
S>Не пробовали? Что лучше? Сколько символов ставите?
Вообще у разных языков и у разных проектов разные традиции именования идентификаторов.
К примеру в C принято использовать краткие наименования. Например mkdir. Доходит до смешного: creat. В эту же категорию можно отнести Go, Rust.
В Java напротив: Files.createDirectory, Files.newOutputStream.
Очевидно, что один и тот же по смыслу код в C будет занимать значительно меньше ширины, чем в Java. Поэтому и подходить с одной линейкой к этим языкам нельзя.
Лично я в C и Go ставлю 80-100 символов. Обычно 100, но 80 для меня не проблема.
В Java ставлю 120, но это не всегда комфортная ширина и даже где-то хотелось бы побольше.
Ширина монитора это не главное ограничение. Главное ограничение это интерфейс слияния, где нужно показывать на экране 3 листинга кода, бок-о-бок. Вот тут с широким кодом действительно бывает неудобно, даже если монитор широкий. Наверное нужно три монитора и софт, который с ними будет работать, может быть тогда будет нормально. Не пробовал.
Здравствуйте, Marty, Вы писали: M>Здравствуйте, netch80, Вы писали: N>>Меня, наоборот, задалбывает документация, статьи, или словари с двумя колонками на страницу. В бумаге ещё нормально читать, а в pdf задалбываешься скроллить. M>Если такое в PDF-е формата A4, то там скорее всего мелкий шрифт. Потому и в две колонки, чтобы можно было нормально читать. Если таким шрифтом в одну колонку сделать, ты офигеешь такое читать. Если нормальный шрифт — то да, это некоторое уродство
Вот из доки:
дока
У них вся дока в таком виде.
А вот из научной статьи:
статья
А вот из словаря:
словарь
и такого вокруг мегатоннами.
Кто-то же заставляет так форматировать?
В современном инструментарии всё чаще используют автоматический форматтер. В последние годы во всех своих проектах я использую именно такой подход. Чем меньше свободы в форматировании кода, тем лучше. gofmt, prettier, python black, clang-format, ну и в принципе почти в любой IDE есть подобный функционал.
И вот если принять за аксиому, что код программистом никак не оформляется, а представляет из себя "жидкую" структуру, которую форматтер может на лету форматировать как душе угодно, тогда вопрос с шириной кода можно вообще отдать на откуп предпочтениям программиста. Открыл код на широком мониторе — форматтер его автоматически отформатировал хоть на 300 колонок. Открыл его в интерфейсе слияния файлов — код переформатировало в 100 символов. При этом на диске он лежит в некоем каноничном виде, и все эти переформатирования никак на это не влияют, это исключительно функционал для отображения.
Здравствуйте, vsb, Вы писали:
vsb>Лично я в C и Go ставлю 80-100 символов. Обычно 100, но 80 для меня не проблема.
Аналогично, для С или похожего кода
vsb>В Java ставлю 120, но это не всегда комфортная ширина и даже где-то хотелось бы побольше.
У меня 150 обычно, если законом в проекте не установлено обратное.
vsb>Ширина монитора это не главное ограничение. Главное ограничение это интерфейс слияния, где нужно показывать на экране 3 листинга кода, бок-о-бок. Вот тут с широким кодом действительно бывает неудобно, даже если монитор широкий. Наверное нужно три монитора и софт, который с ними будет работать, может быть тогда будет нормально. Не пробовал.
Просто монитор недостаточно ширкий
Решается 49" монитором (сейчас цены уже нормальные, конкурентов стало много), три окна side-by-side по 150 колонок входят запросто.
Это как раз ширина двух HD мониторов, всем тут вот рекламирую, доволен как слон, вещь хорошая. IMHO конечно.
Здравствуйте, netch80, Вы писали:
M>>.ua не открывается
N>Поставил на другую локацию,
Я ж говорю, .ua не открывается, а ты опять на .ua выложил
N>но если не сработает, извинити(tm) — сами ищите VPN.
Вот ещё, VPN искать, чтобы .ua сайты разглядывать
У нас тут на кывте у каждого есть хранилище файлов, если что. И даже есть скрипт, который буфер обмена туда заливает, и вставляет ссылку на этот файл прямо в текст сообщения. Какзалось бы, чего уж проще? Но нет, давай раскладывать по каким-то левым сайтам файлы, которые публикуешь тут
Здравствуйте, Alekzander, Вы писали:
A>Часто приходится писать очень структурированный код. Вложенность на пять-шесть уровней, и отступ четыре символа.
Прямо таки просится на рефакторинг по нескольким функциям
A>Ещё иногда очень длинные URL'ы приходится прямо в текст добавлять (не всегда есть смысл выносить их в ресурсы, хотя я к этому стремлюсь).
Здравствуйте, Alekzander, Вы писали:
vsb>>И вот если принять за аксиому, что код программистом никак не оформляется
A>А таблицы? Форматтер же не научить, когда привычную структуру есть смысл заменить на табличную.
Не понимаю вопроса. Я код в табличном виде не пишу. Вопрос про комментарии?
Здравствуйте, vsb, Вы писали:
vsb>Ещё хочу предложить мысль для обдумывания.
vsb>В современном инструментарии всё чаще используют автоматический форматтер. В последние годы во всех своих проектах я использую именно такой подход. Чем меньше свободы в форматировании кода, тем лучше. gofmt, prettier, python black, clang-format, ну и в принципе почти в любой IDE есть подобный функционал.
Нет. одно и тоже можно написать длиной цепочкой, или несколькими последовательными операторами.
Это делает программист. Не форматтер.
Если что-то сдизайнено под длинную цепочку и потом автоматом форматируется, оно становится уже совсем нечитаемым.
И всякие мерджи гита на таком плохо будут работать.
Я при дежживаюсь второго стиля и на своем коде форматтером не пользуюсь, он не нужен просто .
Если только откуда-то достался какой-нибудь неряшливо отформатированный код и надо разобраться, тогда можно форматнуть.
vsb>И вот если принять за аксиому, что код программистом никак не оформляется, а представляет из себя "жидкую" структуру, которую форматтер может на лету форматировать как душе угодно, тогда вопрос с шириной кода можно вообще отдать на откуп предпочтениям программиста. Открыл код на широком мониторе — форматтер его автоматически отформатировал хоть на 300 колонок. Открыл его в интерфейсе слияния файлов — код переформатировало в 100 символов. При этом на диске он лежит в некоем каноничном виде, и все эти переформатирования никак на это не влияют, это исключительно функционал для отображения.
И как я узнаю при редактировании, мои изменения будут помечены как 1 измененная строчка, или весь метод окажется помеченным как измененный?
Здравствуйте, Alekzander, Вы писали:
A>Здравствуйте, Shmj, Вы писали:
A>140
A>Часто приходится писать очень структурированный код. Вложенность на пять-шесть уровней, и отступ четыре символа.
Спасибо за потраченное время, вы нам не подходите.
Здравствуйте, Marty, Вы писали:
A>>Часто приходится писать очень структурированный код. Вложенность на пять-шесть уровней, и отступ четыре символа.
M>Прямо таки просится на рефакторинг по нескольким функциям
Здравствуйте, vsb, Вы писали:
A>>А таблицы? Форматтер же не научить, когда привычную структуру есть смысл заменить на табличную.
vsb>Не понимаю вопроса. Я код в табличном виде не пишу. Вопрос про комментарии?
Здравствуйте, bnk, Вы писали:
A>>>Часто приходится писать очень структурированный код. Вложенность на пять-шесть уровней, и отступ четыре символа.
M>>Прямо таки просится на рефакторинг по нескольким функциям
bnk>А если камаз под водой это YAML или HTML?
YAML/HTML — терпеть, что уж тут сделаешь. Хотя, можно отступы до двух уменьшить, я для XML/HTML так и делаю
Здравствуйте, vsb, Вы писали:
vsb>В современном инструментарии всё чаще используют автоматический форматтер. В последние годы во всех своих проектах я использую именно такой подход. Чем меньше свободы в форматировании кода, тем лучше. gofmt, prettier, python black, clang-format, ну и в принципе почти в любой IDE есть подобный функционал.
vsb>И вот если принять за аксиому, что код программистом никак не оформляется, а представляет из себя "жидкую" структуру, которую форматтер может на лету форматировать как душе угодно, тогда вопрос с шириной кода можно вообще отдать на откуп предпочтениям программиста. Открыл код на широком мониторе — форматтер его автоматически отформатировал хоть на 300 колонок. Открыл его в интерфейсе слияния файлов — код переформатировало в 100 символов. При этом на диске он лежит в некоем каноничном виде, и все эти переформатирования никак на это не влияют, это исключительно функционал для отображения.
Это можно сделать самому. При приёме кода в своё редактирование исправляешь на свои параметры, перед коммитом — загоняешь обратно в местный стандарт.
Вопрос в том, что нет гарантии, что при этом не получится изменения тех частей, которые ты не трогал. С современными форматтерами нет такой гарантии.
Вот если подберёшь заведомо беспроблемный вариант — тогда можешь считать, что всё окончательно OK...