Gems para melhorar a qualidade do seu código

Ano passado, fiz uma talk em um meetup online sobre monitoramento de aplicações.

Na talk ensinei a usar a gem sentry-raven que é a gem que faz a integração toda a máquina de logar os erros da sua aplicação ruby no sentry.

Uma amiga que assistiu a talk comentou que seria legal eu comentar mais sobre gems. Nesse post vou falar sobre as gems que utilizo para padronizar e manter a qualidade do meu código.

Rubocop

O Rubocop é uma gem bastante conhecida e usada na comunidade de ruby. Ela já traz configurada o style guide da linguagem.

O mais legal é que não precisamos seguir fielmente o style guide do Rubocop, podemos adaptar à realidade do nosso time.

Um belo exemplo disso é o limite de 80 caracteres por linha. Se você estudou a história do computador e viu aquelas telas antigas, de 800×600 ou menor, vai lembrar que devido a resolução pouca coisa cabia em uma linha – normalmente 80 caracteres.

Hoje essa limitação já não existe, então esse é um tipo de padrão desnecessário.

Acho válido um limite de caracteres para não ter que ficar usando o scroll lateral. Normalmente eu utilizo 105 caracteres pela resolução compatível com os monitores de todo o time, assim temos uma liberdade maior nesse sentido.

O meu rubocop.yml default para um projeto Ruby on Rails é o seguinte:

Documentation:
 Enabled: false

Metrics/BlockLength:
 Enabled: true
 Exclude:
   - spec/**/*

Metrics/LineLength:
 Max: 105

AllCops:
 Exclude:
   - '**/Rakefile'
   - 'vendor/**/*'
   - 'spec/fixtures/**/*'
   - 'spec/*_helper.rb'
   - 'tmp/**/*'
   - 'bin/**/*'
   - 'db/**/*'
   - 'config/**/*'

No `Documentation`, eu desabilito para evitar alertas do rubocop para comentários no início das classes. Normalmente um model User não precisa de um comentário descrevendo, por isso não vale a pena esse tipo de warning (nesse caso).

O `Metrics/BlockLength` verifica se seus métodos e blocos estão muito grandes.

Acho essa métrica extremamente válida.Você precisa sempre se preocupar em escrever métodos enxutos e respeitando o princípio do Single Responsability (veja esse artigo sobre SOLID). Porém esse cara eu desabilito nos testes, pois testes usando Better Spec tendem a quebrar esse item.

O caso que comentei das 80 linhas é o `Metrics/LineLength`, onde eu altero o default de 80 para 105. Perceba que em cima de uma métrica podemos habilitar, desabilitar, alterar o valor dela, excluir ou incluir arquivos à uma regra.

Por fim, no `AllCops`, estou excluindo todas as regras do Rubocop para uma lista de arquivos. Assim, sempre antes de fazer um push rodando `rubocop -a`, o rubocop, irá aplicar as regras ao seu sistema.

Se estiver algo errado e ele souber como corrigir, ele fará, se não souber ele vai avisar que não sabe e apontar o erro, nesse ponto você precisa ler o erro e alterar conforme a regra para manter seu código padronizado.

Rails best practices

A Gem Rails Best Practices foi uma grata surpresa que tive de conhecer ano passado. Ela é uma gem específica para trabalhar com projetos Rails e ela cumpre muito bem o papel dela. Ela segue a mesma linha de pensamento do rubocop. Ela faz uma varredura no seu projeto e se encontra algo fora do padrão, gera warnings, para que possam ser corrigidos. Há também a possibilidade de habilitar, desabilitar e configurar regras de padronização.

O que mais me chamou a atenção nessa gem é que ela me ajudou muito a sempre aplicar a Lei de Demeter. Eu conhecia, sabia como usar, mas sempre esquecia. E essa gem produz alertas facilitando a aplicação da regra no seu código.

Ela possui outras regras legais como `ProtectMassAssignmentCheck`, que ajudam você a identificar erros de Mass Assignment que você não está vendo e que poderiam estourar erros durante a utilização do sistema.

Já uma regra que foge o padrão é a `UseParenthesesInMethodDefCheck`, que força você a colocar parênteses na declaração de métodos, independentemente de receber parâmetros ou não. Essa eu deixou desabilitada.

Para usar depois de adicionar a gem `rails_best_practices` ao Gemfile do seu projeto Rails, basta rodar o `rails_best_practices -g` para gerar o arquivo de configuração e ajustar ele conforme a necessidade. Para desabilitar e habilitar regras, é só comentar e descomentar a linha. Depois parar rodar o a gem no projeto só usar o `rails_best_practices .`

Ruby critic

Uma das gems mais poderosas quando falamos em qualidade de código é a Ruby Critic. Ela é a união de gems analíticas (Reek, Flay and Flog), com essas gems ela é capaz de gerar um relatório completo do seu código mostrando classes boas e ruins, além de dizer como e onde melhorar.

Um dos pontos fortes é que o Ruby Critic verifica a complexidade ciclomática das classes e da uma nota de A a E na sua classe pelo que é apresentado.

Depois de adicionar a gem ao Gemfile, basta rodar `bundle exec rubycritic`. Assim o ruby critic vai analisar o projeto todo.

Particularmente, prefiro rodar `bundle exec rubycritic app`. Desta forma, ao rodar o Ruby Critic ele irá olhar apenas para a pasta app. Se o projeto tiver uma pasta lib separada da app, basta adicionar ela na frente desta forma: `bundle exec rubycritic app lib`. Faço isso para saber de fato a qualidade do meu código sem olhar para classes do próprio framework e testes (no caso de estarmos trabalhando com Rails).

Uma coisa interessante é que você pode rodar o Ruby Critic para mostrar os resultados no navegador ou no terminal. Para mostrar os resultados no console, basta rodar dessa forma: `bundle exec rubycritic app -f console`. O resultado será mostrado assim:

Para mostrar o resultado no navegador, basta rodar normalmente `bundle exec rubycritic app` e os resultados serão assim:

Desta forma também é gerado um arquivo html no seu projeto normalmente na pasta `tmp/rubycritic/overview.html` . Abrindo a pasta você terá acesso a esse relatório caso tenha fechado a aba.

No vídeo abaixo, mostro o funcionamento de de cada uma das gems, desde o momento que adicionei ela ao projeto até a execução.

Gostou do conteúdo? Quer saber alguma outra coisa a respeito? Dúvidas, sugestões? Deixe um comentário.