Taba ou espaços para indentação? Estatísticas de 3.8 milhões de Perl de arquivos criados por 24 anos

Um dos извечных questões na programação — quais símbolos usar no código do programa para recuo — taba ou espaços.

Às vezes não há escolha. Por exemplo, no Makefile precisa necessariamente usar o taba. Em alemão programação go há um oficial de utilidade gofmt que formata o código e este utilitário usa taba para o recuo. B эзотерическом linguagem de programação Whitespace de taba e espaços não podem ser substituídos uns outro. Mas muitas linguagens de programação, não impõem a escolha, e permitem que o programador decidir quais símbolos usar.

Há bastante popular a opinião de que os personagens usam para o recuo. Opinião para o seguinte: não importa o que usar, o importante é coerência. Se apropriar de taba, então é preciso sempre utilizá-los. Se usar espaços em branco, você só precisa usar os espaços em branco e não use de taba.

Há até mesmo divertido divertido quadrinhos sobre este tema:

(duas pessoas completamente não concordam uns com os outros precisa se utilizar de taba ou espaços, mas absolutamente concorda que você precisa usar apenas uma):

E como as coisas funcionam no mundo real? O que na verdade é usado?

Isso é fácil de descobrir. Você precisa levar os códigos-fonte de programas, a contar os caracteres que são usados e ver os resultados.

Este artigo é o resultado de uma pequena pesquisa sobre o uso de табов e espaços no mundo da linguagem de programação Perl. Há um enorme repositório que armazena o Perl biblioteca — CPAN. Eu baixei todas as versões de todas as bibliotecas que têm agora no CPAN (havia cerca de 135 mil) e achei os caracteres que é usado para o recuo.

Antes de ler, eu sugiro que você no momento para refletir e tentar supor o que é mais popular, para indentação:

  • taba
  • espaços
  • ou uma mistura de табов e espaços

?

Escrevendo o código

Então, a tarefa é compreensível. Precisa de recuperar todas as bibliotecas com CPAN e verificar o que é usado para o recuo.

Para começar, você precisa baixar todo o CPAN. Isto é feito através de um único comando:

time /usr/bin/rsync -av --delete cpan-rsync.perl.org::CPAN /project/CPAN/

3 horas e CPAN descarregado. Ele leva cerca de 27 GB.

CPAN é um conjunto de arquivos são organizados em uma estrutura específica. Aqui está um trecho:

CPAN/authors/id
├── A
│   ├── AA
│   │   ├── AADLER
│   │   │   ├── CHECKSUMS
│   │   │   ├── Games-LogicPuzzle-0.10.readme
│   │   │   ├── Games-LogicPuzzle-0.10.tar.gz
│   │   │   ├── Games-LogicPuzzle-0.12.readme
│   │   │   ├── Games-LogicPuzzle-0.12.tar.gz

Neste exemplo, AADLER — é o login do autor, e Games-LogicPuzzle-0.10.tar.gz e Games-LogicPuzzle-0.12.tar.gz — este comunicados.

Agora no CPAN existem mais de 7 mil autores que baixou a biblioteca no CPAN. Para não armazenar todos os 7 mil pastas em uma única pasta, adicionados níveis (sistema de controle de versão git armazena seus dados de forma semelhante).

No CPAN, você pode carregar bibliotecas, que tinydeal.com diferentes arquivadores.

Eu comecei com o que contou o número de diferentes extensões de arquivos na pasta CPAN/authors/id/. Aqui está um script e o resultado de seu trabalho . Top com extensão de arquivos:

  • .tar.gz 135571
  • .tgz 903
  • .zip 652
  • .gz 612
  • .bz2 243

.tar.gz ganha com essa separação, que eu decidi que será o suficiente para contar os caracteres que são usados ao recuar apenas nas bibliotecas, que transporte em .tar.gz

Eu escrevi vários scripts. Inicialmente não me até o fim da era compreensível em que eu quero para obter dados sobre o табах e lacunas, então eu decidi fazer o sistema consiste em vários componentes. Primeiro pré-processar todos os 135 mil arquivos com lançamentos e colocar os dados sobre a табах e lacunas no banco de dados. Espero que isto vai ser longo. Além de usar os dados do banco de dados para receber dados em diferentes formatos.

Eventualmente ficou script fill_db . Este script заливал os dados no banco de pouco mais de cinco horas. Mas estes cinco horas, isto é, quando já tudo estava preparados. Longe do primeiro lugar script funcionou. Os principais problemas foram com Unicode. Primeiro foi o problema com o lançamento do μ-0.01.tar.gz autor APEIRON, em seguida, houve um problema com os arquivos tipo de t/words_with_ß.dat de lançamento Lingua-DE-ASCII-0.06 autor BIGJ. Mas, no final, todos os problemas foram resolvidos e o script com sucesso atravessou a todos .tar.gz de imprensa.

O script vai por todos .tar.gz arquivos no CPAN. Descompacta .tar.gz a pasta temporária. Encontra nesta pasta temporária, todos os arquivos têm a extensão .pm, .pl, .t ou .pod, lê todos os recuos e verifica se estes ao recuar espaços e / ou taba. Nas versões há outras os arquivos, mas eu decidi limitar-nos apenas os arquivos que explicitamente referem-se ao Perl.

O resultado desse script é 2 tabela no banco de dados. Aqui está um exemplo de dados:

mysql> select * from releases limit 1;
+------------+--------+---------------------------------------------------------------+------------+
| release_id | author | file_name                                                     | timestamp  |
+------------+--------+---------------------------------------------------------------+------------+
|          1 | RUFF   | /cpan/authors/id/R/RU/RUFF/DJabberd-Authen-Dovecot-0.1.tar.gz | 1359325895 |
+------------+--------+---------------------------------------------------------------+------------+
1 row in set (0.00 sec)

mysql> select * from files where release_id = 1;
+---------+------------+--------------------------------------------------------+------+---------------------+-------------------+
| file_id | release_id | file_name                                              | size | has_space_beginning | has_tab_beginning |
+---------+------------+--------------------------------------------------------+------+---------------------+-------------------+
|       1 |          1 | DJabberd-Authen-Dovecot/lib/DJabberd/Authen/Dovecot.pm | 2047 |                   1 |                 1 |
|       2 |          1 | DJabberd-Authen-Dovecot/t/compiles.t                   |   64 |                   0 |                 0 |
+---------+------------+--------------------------------------------------------+------+---------------------+-------------------+
2 rows in set (0.02 sec)

mysql> mysql> selec(*) from releases;
+----------+
| count(*) |
+----------+
|   135343 |
+----------+
1 row in set (0.04 sec)

mysql> select count(*) from files;
+----------+
| count(*) |
+----------+
|  3828079 |
+----------+
1 row in set (5.71 sec)

Somente espaços em branco, só de taba, taba e espaços, e...

Total em um banco de dados sobre cada arquivo na imprensa há 2 bandeira:

  • são espaços em que, ao recuar
  • se o uso de taba em ao recuar

Respectivamente dos dois sinalizadores pode ser de 4 combinações:

  • 11 — são usados e espaços, e de taba
  • 10 — são usados apenas espaços
  • 01 — apenas taba
  • 00 — não usa nem espaços em branco, nem taba

As três primeiras opções é totalmente esperado situação, é o seu eu, e gostaria de encontrar e saber o que é mais popular. E aqui é a opção de 00 — "não se utilizam de taba, nem espaços em branco" é que eu não pensei mas descobriu-se que isso também acontece. "Como?" — você pode perguntar. Aqui está um exemplo.

mysql> select releases.release_id, files.file_name, files.size, has_space_beginning, has_tab_beginning from releases join files on releases.release_id = files.release_id and author = 'KOHA';
+------------+---------------------------------------------------+------+---------------------+-------------------+
| release_id | file_name                                         | size | has_space_beginning | has_tab_beginning |
+------------+---------------------------------------------------+------+---------------------+-------------------+
|     118147 | Bundle-KohaSupport-0.31/lib/Bundle/KohaSupport.pm | 2169 |                   0 |                 0 |
|     118147 | Bundle-KohaSupport-0.31/t/Bundle-KohaSupport.t    |  487 |                   0 |                 0 |
|     118147 | Bundle-KohaSupport-0.31/t/pod.t                   |  130 |                   0 |                 0 |
+------------+---------------------------------------------------+------+---------------------+-------------------+
3 rows in set (0.05 sec)

O autor tem KOHA tem o lançamento Bundle-KohaSupport-0.31. Nesta versão há 3 de arquivo que a expansão da lista de .pm, .pl, .t ou .pod. Sobre todos esses arquivos em banco está escrito que ao recuar não há espaços em branco, nem табов. Como isso pode ser?

Acontece que tudo elementar. Se se olhar para esses arquivos, então eles simplesmente não recuo. Aqui, por exemplo, o conteúdo de um arquivo t/Bundle-KohaSupport.t:

# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl Bundle-KohaSupport.t'

#########################

# change 'tests => 1' to 'tests => last_test_to_print';

use Test::More tests => 1;
BEGIN { use_ok('Bundle::KohaSupport') };

#########################

# Insert your test code below, the Test::More module is use()ed here so read
# its man page ( perldoc Test::More ) for help writing this test script.

De modo que, além dos três é muito esperado situações:

  • são utilizados apenas espaços
  • são utilizados apenas de taba
  • usados e espaços, e de taba

ainda é a situação:

  • não usa nem espaços em branco e não são usados de taba

Os dados sobre os autores

Depois que eu tive os dados processados no banco eu decidi olhar cada autor que ele usa para o recuo.

Eu esperava que o mais popular é o uso de apenas espaços em segundo lugar em popularidade será apenas o uso de табов, e em terceiro lugar em popularidade é a utilização simultânea de табов e espaços.

Mas acabou que eu estava completamente errado.

Eu escrevi um script . Este script verifiquei que os símbolos são usados pelos autores em todos os arquivos .pm, .pl, .t, .pod, que há, em todos os seus lançamentos que têm agora no CPAN.

Eis o que aconteceu:

$ cat app/data/users.log | perl -nalE 'say if /^##/'
## 00 (nothing) - 50 (0.7%)
## 01 (only tabs) - 51 (0.7%)
## 10 (only spaces) - 1543 (21.9%)
## 11 (both) - 5410 (76.7%)

Os dados absolutamente não é como eu esperava!

  • Mais de 75% dos autores usam uma mistura de espaços e табов para o recuo.
  • Apenas espaços em segundo lugar, pouco mais de 20%,
  • e os autores que utilizam apenas taba menos de um por cento.
  • O número de autores, que geralmente não usam o recuo é praticamente o mesmo como o número de autores que utilizam apenas de taba.

A lista completa de todos os autores na desagregados sobre grupos existem em um arquivo no GitHub .

E eis jupyter notebook  com o qual foi construído este gráfico de pizza.

Mas é que os dados gerados por toda a imprensa, que agora há no CPAN. Estes lançamentos foram criados ao longo dos últimos 24 anos. Pode ser com o passar do tempo a relação como algo muda?

Os dados sobre o tempo

Cada arquivo com o lançamento no CPAN tempo de modificação é o tempo quando este lançamento foi carregado no CPAN. Esses dados são carregados no banco de dados. Agora no CPAN o mais antigo de imprensa é Ioctl-0.5 — ele foi carregado no CPAN 1995-08-20:

mysql> select author, file_name, from_unixtime(timestamp) from releases where timestamp = (select min(timestamp) from releases);
+--------+----------------------------------------------+--------------------------+
| author | file_name                                    | from_unixtime(timestamp) |
+--------+----------------------------------------------+--------------------------+
| KJALB  | /cpan/authors/id/K/KJ/KJALB/Ioctl-0.5.tar.gz | 1995-08-20 07:26:09      |
+--------+----------------------------------------------+--------------------------+
1 row in set (0.08 sec)

E neste dia foi submetida imediatamente a 8 de imprensa:

mysql> select * from releases where from_unixtime(timestamp) < '1995-08-21' order by timestamp;
+------------+--------+--------------------------------------------------------------+-----------+
| release_id | author | file_name                                                    | timestamp |
+------------+--------+--------------------------------------------------------------+-----------+
|     112505 | KJALB  | /cpan/authors/id/K/KJ/KJALB/Ioctl-0.5.tar.gz                 | 808903569 |
|      23026 | TYEMQ  | /cpan/authors/id/T/TY/TYEMQ/FileKGlob.tar.gz                 | 808903636 |
|     134031 | WPS    | /cpan/authors/id/W/WP/WPS/Curses-a8.tar.gz                   | 808903647 |
|     112546 | KJALB  | /cpan/authors/id/K/KJ/KJALB/Term-Info-1.0.tar.gz             | 808903748 |
|      70278 | MICB   | /cpan/authors/id/M/MI/MICB/TclTk-b1.tar.gz                   | 808910379 |
|      70274 | MICB   | /cpan/authors/id/M/MI/MICB/Tcl-b1.tar.gz                     | 808910514 |
|      19408 | GBOSS  | /cpan/authors/id/G/GB/GBOSS/perl_archie.1.5.tar.gz           | 808930091 |
|      81551 | JKAST  | /cpan/authors/id/J/JK/JKAST/StatisticsDescriptive-1.1.tar.gz | 808950837 |
+------------+--------+--------------------------------------------------------------+-----------+
8 rows in set (0.06 sec)

Decidi ver como é que muda a distribuição do uso de diferentes símbolos para o recuo no tempo. Para fazer isso, eu escrevi um script .

Aqui está um fragmento de arquivos de dados, que criou um script:

$ cat app/data/releases_date.csv | head
date,00,01,10,11
1995-08-20,0,1,0,7
1995-08-21,0,0,0,0
1995-08-22,0,0,0,0
1995-08-23,0,0,0,0
1995-08-24,0,0,0,1
1995-08-25,0,0,0,0
1995-08-26,0,0,0,0
1995-08-27,0,0,0,0
1995-08-28,0,0,0,0

Т. е. sobre cada data a partir 1995-08-20 não há dados sobre quantos lançamentos divididos pelo fato de quais são os símbolos utilizados para o recuo.

  • 00 — no ao recuar não há espaços em branco, nem табов
  • 01 — no ao recuar utilizados apenas taba
  • 10 — no ao recuar utilizados apenas espaços
  • 11 — em отсутпах usados e de taba e espaços

Mais eu escrevi jupyter notebook  em que desenhou o gráfico. No gráfico apresentarei não absoluto do número de lançamentos, com uma repartição por tipo de recuo, como porcentagem do número total de lançamentos para este dia:

O gráfico quase 9 mil dias. Visto que há uma tendência, mas a programação movimentada e ruim tudo é visível. Porque em vez de dias, eu comecei a группировал lançamentos por mês.:

Surpreendentemente mas traçou uma tendência. O número de lançamentos em que são utilizados apenas de taba ou não são utilizados os recuos praticamente não se altera, mas a proporção de imprensa são apenas espaços está sempre a crescer e este crescimento ocorre por conta da quota de imprensa são uma mistura de табов e espaços.

Por que o aumento de "apenas os espaços em branco". Hipótese número 1

Eu olhei para os dados e me surgiu uma hipótese de porque diminui o número de lançamentos em que é usado, e os problemas e de taba. O meu pensamento sobre o Perl biblioteca Module::Install . Se ao escrever sua a biblioteca é utilizada Module::Install, é o lançamento no CPAN são incluídos os arquivos da biblioteca. E nesses arquivos é uma mistura de espaços e табов. Aqui está um exemplo de arquivo de Módulo::Install na imprensa Devel-PeekPoke-0.04:

mysql> select * from files where release_id = 284 and file_name like '%inc/Module/Install%';
+---------+------------+----------------------------------------------------+-------+---------------------+-------------------+
| file_id | release_id | file_name                                          | size  | has_space_beginning | has_tab_beginning |
+---------+------------+----------------------------------------------------+-------+---------------------+-------------------+
|   10328 |        284 | Devel-PeekPoke-0.04/inc/Module/Install.pm          | 12381 |                   1 |                 1 |
|   10329 |        284 | Devel-PeekPoke-0.04/inc/Module/Install/Metadata.pm | 18111 |                   1 |                 1 |
|   10330 |        284 | Devel-PeekPoke-0.04/inc/Module/Install/Fetch.pm    |  2455 |                   1 |                 1 |
|   10331 |        284 | Devel-PeekPoke-0.04/inc/Module/Install/Makefile.pm | 12063 |                   1 |                 1 |
|   10332 |        284 | Devel-PeekPoke-0.04/inc/Module/Install/Base.pm     |  1127 |                   0 |                 1 |
|   10333 |        284 | Devel-PeekPoke-0.04/inc/Module/Install/WriteAll.pm |  1278 |                   0 |                 1 |
|   10334 |        284 | Devel-PeekPoke-0.04/inc/Module/Install/Win32.pm    |  1795 |                   1 |                 1 |
|   10335 |        284 | Devel-PeekPoke-0.04/inc/Module/Install/Can.pm      |  3183 |                   1 |                 1 |
+---------+------------+----------------------------------------------------+-------+---------------------+-------------------+
8 rows in set (0.03 sec)

Minha hipótese é de que os desenvolvedores usam os espaços para indentação, mas devido ao fato de que na imprensa está Module::Install então, as estatísticas são contadas e espaços, e de taba. Module::Install tornaram-se menos usar (assim como surgiram todos os tipos de Dist::Zilla, Dist::Milla, Minilla) e, portanto, Module::Install parou de dar a distorção.

Esta hipótese precisa verificar. Primeiro eu decidi ver se realmente Module::Install são utilizados menos e menos. Eu construí um gráfico. Cada ponto é um número de lançamentos para o mês em que utilizou Module::Install. Visto que a parte a hipótese nula é verdadeira — realmente, Module::Install começaram a usar menos.

Mas, de fato, se o uso Module::Install afeta a quota de utilização de espaços ou табов e espaços para o recuo. Para descobrir isso, eu desenhei mais de dois gráficos. Este é o número de diferentes tipos de recuo em lançamentos de mês em mês. No primeiro gráfico só libera usam Module::Install, no segundo gráfico apenas lançamentos em que ele não é usado.

Dá pra ver que realmente, se utilizar a biblioteca de Módulo::Install, então, mais frequentemente na biblioteca usado é uma mistura de табов e espaços.

E aqui está um gráfico que exibe somente os lançamentos que não utilizam o Module::Install. Se compararmos este o gráfico com o gráfico no qual se voltam todos os lançamentos, então a diferença é, mas nada de fundamentalmente, não muda.

Verifica-se que a hipótese estiver errada. Se a imprensa é usada Module::Install, o lançamento, muitas vezes cai no grupo de "taba e espaços", mas se não considerar todos os lançamentos em que é usado Module::Install, ainda temos a tendência — a proporção de imprensa em que são utilizados apenas de taba como o recuo cresce a proporção de imprensa em que são utilizados uma mistura de табов e espaços.

Por que o aumento de "apenas os espaços em branco". Hipótese número 2

Por que o mesmo ainda está crescendo o número de lançamentos em que são utilizados apenas de taba? Pode ser algum tipo de excesso ativa o autor, que liberam muito muitos lançamentos e essas autor tão afetam todas as estatísticas?

Eu tentei verificar. Desenhou um gráfico que mostra a proporção de imprensa em que foram utilizados apenas os espaços, mas célula da primeira letra do nome do autor. Se realmente algum tipo de o autor fez sobre uma grande contribuição para o total, então, qual a linha é muito drasticamente iria para cima. No mesmo gráfico, que eu vi, todas as linhas mais ou menos lisos. Assim que a confirmação desta hipótese, eu não poderia receber.

Por que o aumento de "apenas os espaços em branco". Hipótese número 3

O gráfico mostra que, com o passar do tempo, torna-se cada vez mais lançamentos que são usados apenas espaços para indentação. E essa proporção está crescendo por conta de imprensa em que é uma mistura de espaços e табов.

Minha primeira hipótese foi de que isso ocorre por que em versões mais cedo ativamente incluíram o código da biblioteca de Módulo::Install em que utilizou uma mistura de espaços e табов, essa biblioteca usam cada vez menos, e assim a proporção de imprensa em que é uma mistura de табов e espaços reduzidos. Descobriu-se que uma parte da verdade em que há, mas mesmo se retirar da a consideração de todos os lançamentos que usa Module::Install, a tendência geral é a de não mudar — ainda a proporção de imprensa em que apenas espaços que cresce a proporção de imprensa em que é uma mistura de espaços e табов.

A minha segunda a suposição de que modo afectam as estatísticas muito pequeno conjunto muito ativa dos autores. Eu não era capaz de encontrar a confirmação desta hipótese.

Minha terceira hipótese é a de que os autores aparecem mais confortável editores de texto e IDE, através do qual torna-se mais fácil de usar консистентно espaços, e não uma mistura de espaços e табов. Mas, infelizmente, as idéias de como testar essa hipótese eu não tenho. Nos dados que se encontram no CPAN não há informações sobre qual o editor foi usado quando você cria esse lançamento. Eu olhei para a data de lançamentos editores populares/IDE:

  • Emacs — 1985
  • vim — 1991
  • IntelliJ IDEA — январяь 2001
  • Eclipse — novembro de 2001
  • Sublime Text — janeiro de 2008
  • Atom — fevereiro 2014
  • VS Code — abril de 2015

Os dados sobre os autores para o ano de 2019

Anterior gráficos visto que com o passar do tempo, torna-se cada vez mais lançamentos que são usados espaços, e não uma mistura de табов com espaços. Então eu decidi ver a distribuição de quais tipos de recuo é usado pelos autores somente com base nos seus lançamentos para o ano de 2019.

Os dados dos resultados da execução do script :

$ cat app/data/users_2019.log | perl -nalE 'say if /^##/'
## 00 (nothing) - 12 (1.4%)
## 01 (only tabs) - 9 (1.0%)
## 10 (only spaces) - 355 (41.2%)
## 11 (both) - 486 (56.4%)

Se compararmos os dados sobre os autores para 2019 o ano e os dados de todos os anos, vê-se que porcentagem de autores que usa apenas taba praticamente não se altera, mas a parte de os autores que utilizam apenas as lacunas aumentou fortemente.

A fonte para este gráfico de pizza:

Fatores que afetam a correção de dados

Para a formação de números e gráficos foram utilizados todos .tar.gz lançamentos, que estavam no CPAN no momento da escrita deste artigo, além de lançamentos do próprio a linguagem de programação Perl.

CPAN permite a exclusão de lançamentos, dados que são mostrados neste artigo excluídos lançamentos não participaram. Não está claro o quão forte são os dados se em consideração os caracteres de avanço no já remoto lançamentos. É possível que os dados são fortemente. Há um arquivo de backpan  que armazena todos os lançamentos, que já estavam no CPAN. Assim, em teoria, há a possibilidade de recalcular todos os tendo em conta o número de lançamentos que já não estão no CPAN.

O segundo ponto, que afeta a precisão dos dados é o de que não foram considerados símbolos o recuo apenas em lançamentos, que foram de tinydeal.com em .tar.gz arquivo. Outros tipos de arquivos não utilizados. A grande maioria dos lançamentos é .tar.gz, assim que foi feita essa suposição. Se recalcular os dados de todos os arquivos de dados com certeza vai mudar. Acho que a mudança não será mais alguns por cento.

O código-fonte

Todo o conjunto de scripts que foram utilizados para a coleta de dados, os dados em si e jupyter laptops tudo está disponível no repositório no GitHub.

O código que é escrito — ele está muito longe de ser perfeito. Tudo o que estava escrito escrito com idéias mais rápido possível obter um resultado, e não de criar um código de promoção.

Resumo

No momento da redação deste texto no repositório de bibliotecas Perl CPAN foram cerca de 135 mil lançamentos. O primeiro lançamento foi feito 24 anos (1995-08-20). Em um desses lançamentos é de quase 4 milhões de arquivos com as extensões de .pm, .pl, .t ou .pod.

Se considerados os dados de todos os tempo, constata-se que 76.7%% de autores ao recuar usam uma mistura de espaços e табов, 21.9% usam ao recuar apenas espaços e 0.7% — só de taba.

Mas se considerar somente os dados, no ano de 2019, torna-se cada vez mais dos autores que utiliza apenas os espaços em branco para o recuo, mas, ainda assim, a maioria usa uma mistura de табов e espaços (56.4% — utilizam e de taba e espaços,espaços 41.2% — somente espaços em branco, 1.0% — só de taba).

E se você olhar para o gráfico de uma quota de utilização de vários tipos de recuo, vê-se que a proporção o uso de apenas espaços cresce e esta percentagem cresce a participação de quem usa uma mistura de табов e espaços para indentação.

Não se sabe exatamente por que esta proporção está crescendo. É possível que isso acontece devido ao fato de que os autores usam-se mais confortáveis editores de texto, que permitem mais simples e segura de instalar quais símbolos usar para o recuo.

Outros artigos