Немного о компьютере

Стиль программирования пробелы или табы. Андроид, финты ушами.: Табуляция или пробелы? Различия в поведении пробелов и табов

Для пытливых разработчиков до сих пор остается актуальным вопрос использования табуляции и пробелов для форматирования кода. Могут ли они быть взаимозаменяемы: например, 2 пробела на табуляцию или 4? Но единого стандарта нет, поэтому иногда между разработчиками возникает непонимание. Кроме того, различные IDE и их компиляторы обрабатывают табуляцию также по-своему.

Решением вопроса обычно становится соглашение о правилах форматирования в рамках проекта или языка программирования в целом.

Команда разработчиков из Google исследовала проекты в репозитории Github. Они проанализировали код, написанный на 14 языках программирования. Целью исследования было выявить соотношение табуляций и пробелов - то есть, наиболее популярный способ форматирования текста для каждого из языков.

Реализация

Для анализа использовалась уже существующая таблица , в которую записаны наименования репозиториев Github.

Напомним, что около двух месяцев назад весь открытый код Github стал доступен в форме таблиц BigQuery.

Однако для анализа были выбраны не все репозитории, а только верхние 400 тысяч репозиториев с наибольшим числом звёзд, которые они получили за период с января по май 2016 года.

Из этой таблицы были выделены файлы, содержащие код на 14 самых популярных языках программирования. Для этого в качестве параметров sql-запроса были указаны расширения соответствующих файлов – .java, .h, .js, .c, .php, .html, .cs, .json, .py, .cpp, .xml, .rb, .cc, .go.

SELECT a.id id, size, content, binary, copies, sample_repo_name , sample_path FROM (SELECT id, FIRST(path) sample_path, FIRST(repo_name) sample_repo_name FROM WHERE REGEXP_EXTRACT(path, r"\.([^\.]*)$") IN ("java","h","js","c","php","html","cs","json","py","cpp","xml","rb","cc","go") GROUP BY id) a JOIN b ON a.id = b.id

864.6s elapsed, 1.60 TB processed

Запрос выполнялся довольно долго. И это неудивительно, так как было необходимо выполнить операцию объединения (join) таблицы из 190 миллионов строк с таблицей в 70 миллионов строк. Всего было обработано 1,6 ТБ данных. Результаты запроса доступны по этому адресу .

В таблице записаны файлы без своих дубликатов. Ниже указано общее количество уникальных файлов и их суммарный размер. Дубликаты файлов не учитывались в ходе анализа.

После этого оставалось только сформировать и запустить на выполнение финальный запрос.

SELECT ext, tabs, spaces, countext, LOG((spaces+1)/(tabs+1)) lratio FROM (SELECT REGEXP_EXTRACT(sample_path, r"\.([^\.]*)$") ext, SUM(best="tab") tabs, SUM(best="space") spaces, COUNT(*) countext FROM (SELECT sample_path, sample_repo_name, IF(SUM(line=" ")>SUM(line="\t"), "space", "tab") WITHIN RECORD best, COUNT(line) WITHIN RECORD c FROM (SELECT LEFT(SPLIT(content, "\n"), 1) line, sample_path, sample_repo_name FROM HAVING REGEXP_MATCH(line, r"[ \t]")) HAVING c>10 # at least 10 lines that start with space or tab) GROUP BY ext) ORDER BY countext DESC LIMIT 100

16.0s elapsed, 133 GB processed

Анализ каждой из строк 133 Гб кода занял 16 секунд. Добиться такой скорости помог все тот же BigQuery.


Чаще всего табуляция встречается в языке С, а пробелы - в Java.

Хотя для кого-то соотношение тех или иных управляющих символов не имеет значения, а споры на эту тему кажутся надуманными. Это не имеет значения и для некоторых IDE, которые сохраняют табуляцию как некоторое количество пробелов. Также существуют IDE, в которых это количество можно настраивать вручную.

Некоторое время назад эта проблема была обыграна в сериале «Кремниевая долина». Парень и девушка не сошлись в вопросе форматирования. В результате старый холивар не только привел к недопониманию в профессиональном плане, но и создал проблемы в их личных отношениях.

Для пытливых разработчиков до сих пор остается актуальным вопрос использования табуляции и пробелов для форматирования кода. Могут ли они быть взаимозаменяемы: например, 2 пробела на табуляцию или 4? Но единого стандарта нет, поэтому иногда между разработчиками возникает непонимание. Кроме того, различные IDE и их компиляторы обрабатывают табуляцию также по-своему.

Решением вопроса обычно становится соглашение о правилах форматирования в рамках проекта или языка программирования в целом.

Команда разработчиков из Google исследовала проекты в репозитории Github. Они проанализировали код, написанный на 14 языках программирования. Целью исследования было выявить соотношение табуляций и пробелов - то есть, наиболее популярный способ форматирования текста для каждого из языков.

Реализация

Для анализа использовалась уже существующая таблица , в которую записаны наименования репозиториев Github.

Напомним, что около двух месяцев назад весь открытый код Github стал доступен в форме таблиц BigQuery.

Однако для анализа были выбраны не все репозитории, а только верхние 400 тысяч репозиториев с наибольшим числом звёзд, которые они получили за период с января по май 2016 года.

Из этой таблицы были выделены файлы, содержащие код на 14 самых популярных языках программирования. Для этого в качестве параметров sql-запроса были указаны расширения соответствующих файлов – .java, .h, .js, .c, .php, .html, .cs, .json, .py, .cpp, .xml, .rb, .cc, .go.

SELECT a.id id, size, content, binary, copies, sample_repo_name , sample_path FROM (SELECT id, FIRST(path) sample_path, FIRST(repo_name) sample_repo_name FROM WHERE REGEXP_EXTRACT(path, r"\.([^\.]*)$") IN ("java","h","js","c","php","html","cs","json","py","cpp","xml","rb","cc","go") GROUP BY id) a JOIN b ON a.id = b.id

864.6s elapsed, 1.60 TB processed

Запрос выполнялся довольно долго. И это неудивительно, так как было необходимо выполнить операцию объединения (join) таблицы из 190 миллионов строк с таблицей в 70 миллионов строк. Всего было обработано 1,6 ТБ данных. Результаты запроса доступны по этому адресу .

В таблице записаны файлы без своих дубликатов. Ниже указано общее количество уникальных файлов и их суммарный размер. Дубликаты файлов не учитывались в ходе анализа.

После этого оставалось только сформировать и запустить на выполнение финальный запрос.

SELECT ext, tabs, spaces, countext, LOG((spaces+1)/(tabs+1)) lratio FROM (SELECT REGEXP_EXTRACT(sample_path, r"\.([^\.]*)$") ext, SUM(best="tab") tabs, SUM(best="space") spaces, COUNT(*) countext FROM (SELECT sample_path, sample_repo_name, IF(SUM(line=" ")>SUM(line="\t"), "space", "tab") WITHIN RECORD best, COUNT(line) WITHIN RECORD c FROM (SELECT LEFT(SPLIT(content, "\n"), 1) line, sample_path, sample_repo_name FROM HAVING REGEXP_MATCH(line, r"[ \t]")) HAVING c>10 # at least 10 lines that start with space or tab) GROUP BY ext) ORDER BY countext DESC LIMIT 100

16.0s elapsed, 133 GB processed

Анализ каждой из строк 133 Гб кода занял 16 секунд. Добиться такой скорости помог все тот же BigQuery.


Чаще всего табуляция встречается в языке С, а пробелы - в Java.

Хотя для кого-то соотношение тех или иных управляющих символов не имеет значения, а споры на эту тему кажутся надуманными. Это не имеет значения и для некоторых IDE, которые сохраняют табуляцию как некоторое количество пробелов. Также существуют IDE, в которых это количество можно настраивать вручную.

Некоторое время назад эта проблема была обыграна в сериале «Кремниевая долина». Парень и девушка не сошлись в вопросе форматирования. В результате старый холивар не только привел к недопониманию в профессиональном плане, но и создал проблемы в их личных отношениях.

".
Я хотел было ответить к комментариях, но в силу объема и желания независимости от исходного топика решил создать новый топик.

Итак, под катом - почему табы лучше пробелов, самые значительные заблуждения касательно табов и как ими правильно пользоваться.

Начнём с того, что большинство людей (по крайней мере на Хабре) предпочитают табы.

На самом деле странно то, что многие до сих пор не отличают indentation и alignment. Ну, вот это - indentation:
for (int i = 0; i < 10; i++) { if (a[i] == 0) do_something(i); }

А вот это - alignment:
int some_variable = 0; int v1 = 0;

Первое можно делать и табами, и пробелами, но когда делаешь табами - каждый может подстроить ширину indent"а на свой вкус и ничего никуда не едет. А второе - строго пробелами.

В IDE есть опция Smart Tabs для этого:

Если правильно использовать табы (а именно - только для indentation) - можно без проблем менять размер табов не нарушая стиль программирования.

2 пробела на таб:

5 пробелов на таб:

9 пробелов на таб:

Так каких проблем мы лишаемся?

1. Каждый программист может настроить длину табуляции под свой вкус. Всегда работает на практике. Когда код с большой вложенностью - можно поставить ширину табуляции в два пробела, иначе - в четыре.
2. Легче работать с посторонними библиотеками. Какие-то библиотеки поддерживают стиль с шириной таба в два пробела, какие-то с шириной в четыре пробела. Только использование табов не накладывает ограничение на стиль.

Процитирую пару мыслей из предыдущего топика:

Тяжело работать с проектами, где используются библиотеки, содержащие в тесте табуляции. Предположим, в одной библиотеке табуляция равна 3 символам, в другой 4 символам. А вы в проекте используете 2 символа. В результате какая-то часть кода у вас будет отображаться в редакторе со сбитым форматированием.

На самом деле в проектах, которые используют табуляцию таких проблем нету - так как табуляция безразмерна, а вот поддерживать одновременно пару библиотек с разным размером пробело-табуляции становится проблематичным, т.к. уже нельзя пользоваться tab (чтобы IDE заменяла табы на пробелы). Конечно, есть шанс решить такую проблему разными проектами с разными настройками, но это тот еще костыль, да и башку все-равно сносит от разных размеров вложенности.
Легко пустить козла в огород. Скажем у вас табуляция равна 4 пробелам. Кто-то что-то чуть-чуть поправил, используя другой размер табуляции или явно вставив пробелы. У него все смотрелось нормально, а у вас строчка кода куда-то уедет.

Аналогично, табуляция - безразмерная. Такая проблема есть только в проектах, которые используют пробелы. Там где используются табы - они могут быть хоть 2, хоть 10 символов шириной.
Надо постоянно настраивать различные редакторы под нужный вам размер табуляции. Даже если вам нужно просто посмотреть код не правя. Иначе все разъезжается. Особенно это не удобно, когда приходится что-то делать со своим кодом на сторонней машине.

Допустим, я открываю Kate, чтобы по-быстряку поправить код в каком-то файле. Оппа, размер табуляции два пробела. Надо лезть в конфиг. А в соседнем файле из другой либы - четыре пробела. Придётся пользоваться пробелом вместо таба для отступов, ужас. С табами такой проблемы нету.
Лишние сложности тем, кто работает одновременно с проектами, где по стандартам кодирования требуются разные отступы. Если стандарты требуют использование табуляции, то это ещё тот вечно ноющий зуб. В случае пробелов опять-таки все намного проще.

Как выше разобрали, такая проблема есть именно с проблемами, а не с табами.

А еще дополнительно у пробелов есть такие недостатки, как невозможность быстрого перемещения стрелочками клавиатуры (щёлкает каждый пробел, а не через блок), возможность допустить ошибку (поставить в одном месте 3 пробела вместо 4, чем порушить дальнейшую структуру), увеличение размера файла и куча всего ещё.

Вывод

У пробелов нету ни одного существенного преимущество по сравнению с табами, при этом мы не сковываем программиста в рамки и не заставляем его мучаться с слишком маленькими (или слишком большими) для него табами.

Главное

Не так важно, что именно вы используете. Важно, чтобы вы следили за порядком своего кода и всегда придерживались одного и того же стиля . Включите отображение табов/пробелов, иногда меняйте размер табуляции на другой и пробегайте глазами код, чтобы удостоверится, что у вас где-то не вставились пробелы вместо табов или табы вместо пробелов.

UPD: примечание согласно комментариев

Я давно хотел написать статью про табы. Но не про «Табы VS Пробелы», а именно про то, как пользоваться табами правильно. Комменты подтвердили, что многие не знали про indentation и alignment. Смысл этой статьи совершенно не в том, что правы все, кто использует табы. Есть стандарты кодирования, есть особенности языка, есть личные предпочтения.
Самое главное - знать правила расстановки отступов и уметь ими пользоваться. И никогда не смешивать два стиля. Заметьте - не «не смешивать табы и пробелы», а не смешивать два стиля.
Лично я рекомендую использовать подход, описанный в топике, но только в том случае, если стандарты кода, с котором вы работаете не подразумевают что-то другое.

Бывают случаи, когда не хочется менять стили ради какого-то одного элемента, или необходимо вставить несколько пробелов в тексте из соображений эстетики или стилистики форматирования текста. И тут встает вопрос: «Как сделать пробел в HTML, чтобы текст красиво отображался, и при этом избежать избыточности кода?» Для этого рассмотрим виды пробелов и примеры их использования в HTML-коде.

Неразрывный пробел HTML

В случаях, когда нужно не отрывать части текста друг от друга, поможет неразрывный пробел , код которого выглядит следующим образом:

Это так называемый, "non breaking space".

Примеры использования неразрывного пробела:

И т. д. т. к. Е. Велтистов 11 тыс. рублей

Тонкий пробел

Код пробела HTML, который мы рассмотрели выше, является повсеместным. Но бывают случаи, когда обычный пробел оказывается слишком «большим». Тогда на смену ему приходит тонкий пробел . Это пробел, ширина которого составляет четверть кегля используемого шрифта. Обозначается тонкий пробел следующим образом:

и используется, по большей части, для разбиения разрядов чисел, например, "15 000 000 долларов" стоит записать так:

15 000 000 долларов

Примечание: Тонкий пробел может некорректно отображаться в старых версиях некоторых из браузеров, но во всех последних версиях работает на «ура».

Другие типы пробелов в языке HTML

Помимо наиболее актуальных видов, что мы рассмотрели выше, существуют и другие.

  •   - пробел длины буквы N;
  •   - пробел длины буквы M;
  • ‌ - несоединяющий символ нулевой длины;
  • ‍ - соединяющий символ нулевой длины.

Примечание: Если вам нужно поставить несколько пробелов подряд, обрамите текст тегом

:

Конструктор сайтов «Нубекс»

Пробел при помощи CSS

Вариант создания табуляции (отступа) с помощью CSS можно решить с помощью следующего приёма:

Конструктор сайтов «Нубекс»

Стили расстановки скобок - не единственное поле, на котором происходят баталии войны стилей программирования. Способы использования пробелов также оказывают значительное влияние на читабельность вашего кода. Если вы думаете, что где-то должен быть, конечно, один стиль расстановки пробелов, которого придерживается каждый программирующий для максимизации читабельности своего кода, я боюсь, вы ошибаетесь. Здесь имеется столько стилей расстановки пробелов, сколько существует С-программистов.

Отступы

Что представляют собой правильные установки табуляции и отступов? Чаще всего выбирают два, три, четыре, восемь пробелов или ни одного. Я надеюсь, вы согласитесь, что мы можем отклонить нулевой вариант как делающий код полностью нечитабельным, но все другие варианты являются вполне читабельными.

Большинство программистов начинают с использования заданной по умолчанию установки табуляции, которая часто имеет восемь колонок в ширину (но не обязательно; это зависит от вашего текстового процессора). Постепенно, особенно в случае большого числа уровней отступов, код начинает выглядеть немного растянутым:

int foo(int arr[А][В][С])
{
int а, Ь, с, total = 0;
for (а = 0; а < А; а++)
{
for(b = 0; Ь < В; Ь++)
{
fоr(с = 0; с < С; С++)
{
total += arr[a](b][c];
}
}
}
return total;
}

Поэтому многие уменьшают количество пробелов до четырех:

int foo(int bar[А][В][С])
{
int a, b, c, total = 0;
for(a = 0; a < A; a++)
{
for(b = 0; b < B; b++)
{
for(c = 0; с < C; С++)
{
total += bar[a][b][c];
}
}
}
return total;
}


Лично я пользовался таким способом на протяжении многих лет. Многим позже я обнаружил, что для моих целей наиболее удобными оказываются отступы в два пробела. Это была установка, от которой я не отступаю уже длительное время. Я приобрел привычку использовать два пробела, когда начал регулярно публиковать статьи в Usenet. Я использовал клавишу пробела вместо табулятора не только потому, что установка табулятора у моих читателей дает слишком широкий отступ, но мне также не нравилась сама идея вставки табуляции в публикации Usenet. Коль скоро такое решение было принято, я быстро обнаружил, что уменьшение количества символов пробела в 12 раз для трехуровневого отступа позволяет мне сэкономить немало времени, так что я начал использовать отступы в два пробела. К своему удивлению, я нашел, что мне нравится это больше, чем четыре пробела, так что теперь я использую два пробела все время.

Отступ в три пробела для многих С-программистов представляется неестественным. Тем не менее, он используется на некоторых сайтах, и при этом текст выглядит неплохо.

Какая же установка табуляции и отступа является правильной? Вы опередили меня, я знаю - действительно, нет одного правильного уровня. Если вашим проектом стандарта кодирования предусмотрена установка, которую вы должны использовать, выберите уровень, который, по вашему мнению, выглядит наиболее читабельно, используйте его последовательно в своей программе и будьте готовы пересмотреть свое мнение через некоторое время.

Табуляторы и мэйнфреймовские компиляторы

Некоторые мэйнфреймовские С-компиляторы не отвечают должным образом на вставку символов табуляции в исходные файлы. Если вы чувствуете, что попадаете в собственную ловушку, может оказаться необходимым потратить время (или деньги) на программный инструмент для замены табуляции пробелами. Фактически вы можете уже иметь такой инструмент. Например, редактор Microsoft Visual С++ имеет эту возможность.

Пробелы вокруг символов

Для улучшения читабельности программного кода следует творчески подходить к использованию пробелов. Снова-такигиет единственно правильного способа расстановки пробелов, но неправильных способов - множество. В приведенном ниже примере пробелы использованы скверно:

#include
#include
#define P printf
#define I atoi
int main(int a,char*v
){int r=5, i;if(a>l
) r=l(v}

Похожие публикации