Deixando seu código mais legível
December 6th, 2008
Finalmente saiu a maioria dos vídeos da Rubyconf 2008. E tem muito material interessante. Como prometido, falarei um pouco da palestra de Micheal Granger. Achei a palestra razoável, algumas coisas um pouco óbvias e algumas dicas que eu não tinha conhecimento.
Apresentarei aqui, resumidamente, as idéias passadas pelo palestrante.
Você encontra Michael Granger no canal ruby-talk da freenode, seu apelido é ged. Ele utiliza Ruby desde 2001 e esteve em 6 Rubyconfs desde então. Granger trabalha em um estúdio de animação em Portland chamado Laika. Ele participa ativamente de uma dezena de projetos open source como, por exemplo, o Bluecloth e criou o tema padrão do RDoc.
A idéia de Granger é a de aplicar os príncipios do design visual para o código com objetivo de melhorar a comunicação deste com os seus leitores . O palestrante falou que evitaria entrar em questões polêmicas como, por exemplo, se é melhor utilizar dois ou quatro espaços para identar o código. Estes tipos de detalhes são escolhas pessoais que variam com o estilo do programador. O que ele apresentará são sugestões que nem sempre servirão para você mas em geral são válidas.
Código é comunicação. É um conjunto de instruções para uma máquina. Mas é primariamente uma comunicação de idéias entre seres humanos. Estas pessoas, a audiência do código, são seus parceiros de trabalho, outras pessoas que irão alterar o código (no caso de um projeto open source) ou aprender com ele e, em muitos casos, você mesmo, que terá que olhar para um código seu escrito a meses atrás para melhorá-lo, consertá-lo ou adicionar funcionalidades. É normal olharmos para o nosso próprio código e pensarmos, “Puxa, eu escrevi isso!?”
Pa lermos o código de maneira eficiente precisamos maximizar o “fluxo”. O Fluxo, segundo Mihaly Csikszent, é “a sensação de completude e foco energizante em uma atividade, com alto nível de prazer e satizfação”. Existem alguns critérios para que o fluxo seja mantido:
- imersão completa no que faz;
- sabe o que tem que fazer a cada momento;
- tem um feedback rápido e preciso de quão bem você está fazendo;
- e um sentimento de que suas habilidades são desenvolvidas mas não são superadas pelas necessidades de ação.
Com pouco esforço podemos fazer mais para tornar nosso código mais legível e assim aumentar o fluxo. Por que não gostariámos de fazê-lo?
Por misantropia, exagerando, por não gostarmos da humanidade. Alguns progamadores acreditam que ler código deve ser difícil, que nem todas as pessoas têm o direito de entender o que se passa. Ou por pânico em querer terminar o código o mais rápido possível. Porém a comunidade Ruby em geral não sofre destes dois problemas. O problema principal é a austeridade, isto é, um senso de simplicidade na aparência e estilo do código, já que a linguagem nos incentiva a escrever as coisas de maneira simplificada. Mas nem sempre devemos tomar este caminho.
Então, o design adiciona estruturas e signficados para a comunicação usual. Granger pergunta: Sou um programador, o que eu sei sobre design visual? Ele nos introduz ao livro: “The non-designers design book” de Robin Williams, uma boa introdução para programadores sobre design que foi recomendado ao palestrante por um colega da área de usabilidade.
Este livro apresenta os quatro príncipios básicos do design (a sigla CRAP):
Contraste
Coisas que são diferentes devem parecer bastante diferentes. O mais importante numa página deve ser aquilo que chama a atenção do usuário na primeira vez em que ele olha para ela.
Por convenção, já aplicamos várias regras para constraste:
# Símbolos que são adicionados a variáveis ditinguem # entre identificadores comuns e identficadores não usuais): variavel_local @variaveis_de_instancia @@variaveis_de_classe $globais # Constantes que na verdade são classes contra constantes "Puras" BasickSocket DEFAULT_DEPTH # Blocos de uma linha contra blocos de multiplas linhas ary.map {|thing| thing.inspect } ary.each do |thing| next if thing.tainted? || thing.imediate_object? list << thing end
Granger então dá algumas sugestões.
Distinguirmos chamadas a métodos de variáveis locais.
filters.each{ |filter| ... }
Neste código, filters é uma variável local ou uma chamada de método? A distinção entre estes dois tipos pode ser facilmente obtida adicionando um ”self.” no caso em que o parâmetro em questão é um método, mostrando que há uma chamada de método da classe em questão. O ponto indica que há uma mensagem sendo passada, portanto uma ação.
self.filters.each{ |filter| ... }
Olhando para o mesmo código não há ambiguidade. Não precisaremos procurar no código para saber o que é “filters” pois já sabemos imediatamente que é uma chamada de método.
Outro exemplo são métodos de classe. Olhando para os métodos abaixo (parte do código do ActionController::Base do Rails) é difícil saber que eles são métodos de classe apenas olhando para esta parte do código.
def prepend_with_path( path ) ... ... ... end def append_view_path( path ) ... ... ... end
Isto porque esta informação está 300 linhas acima:
class << self
Então você pode usar o estilo de declaração de método do singleton, empregando o operador de escopo (*::*) e deixando mais claro que estes são métodos de classe e não métodos de instância nem apenas mensagens sendo passadas.
def self::prepend_with_path( path ) ... ... ... end def self::append_view_path( path ) ... ... ... end
Repetição
Coisas similares devem permanecer parecidas. A consistência é um ponto chave.
No código podemos alterar as relações espaciais e as espessuras das linhas.
A primeira sugestão dada é a de se usar comentários para o auxílio na navegação.
##################################### ### C L A S S M E T H O D S ##################################### ##################################### ### I N S T A N C E M E T H O D S #####################################
O uso destes blocos é interessante para marcar diferentes escopos dentro do código.
Um segundo marcador menos óbvio e forte no código é usar marcadores para destacar modificadores de comportamento do código.
############## funcao_de_modulo ############## ##### public ##### ####### protected ####### ##### private #####
E o terceiro método é usar marcadores para delinear métodos. Assim, os códigos no alto dos métodos serão distinguidos do código dentro do método no Rdoc.
### Method documentation def a_method # comments of a trick bit of the method self.some_trucky_stuff end
Alinhamento
Coisas que tem alinhamento em seu propósito devem estar alinhadas visualmente. Os elementos não podem ser dispostos arbitrariamente.
A maioria das pessoas já segue esse conselho em algum nível. É comum que usemos identação de código. Existem outras coisas que você pode fazer, além de identar o código. Como, por exemplo, alinhar os operadores, para que fique mais fácil de se ler que um grupo de linhas está fazendo coisas similares (no exemplo aqui no blog não ficou perfeito já que essa fonte não é mono-espaçada).
def initialize( name, description, host, port ) @name = name @description = description @host = host @port = port end
E também alinhar cláusulas condicionais no final de uma linha:
seld.send_notification if self.something_has_changed && self.user_wants_notification? && self.user_is_reachable?
Ou métodos indivduais de uma longa cadeia de métodos:
lines.collect {|str| str.chomp }. reject {|str| str =~/^\s*($.+)$/ }. collect {|str| str.scan(/\w+/) }. flatten. uniq
Outra boa prática é adicionar espaço aos seus parênteses (colchetes e chaves para o casso de arrays e hases) para tornar mais fácil a visualização dos argumentos.
def initialize( name, description ) ... end servers = [ ['localhost', 1414], ['staging', 2014] ]
Proximidade
Coisas relacionadas devem ser agrupadas.
Michael acredita que esse é o mais importante dos príncipios. Ele diz que um exemplo básico disso é a organização de seus arquivos. É interessante também o uso de espaçamento vertical (linhas em branco) para separar partes do código que se relacionam para que esta relação fique clara visualmente. Métodos como vários argumentos não devem ter os parênteses omitidos, isso dificulta a letura.
Concluindo, Granger nos reitera que código é comunicação e que devemos aprender com os designers para que possamos escrever código mais legível e assim economizar tempo no futuro, quando nós mesmos ou outras pessoas lerão nosso código.
Depois dessa palesta, já vi que tenho muitas linhas de código a serem editadas. Se tiverem sugestões de como escrever um código mais legível, não deixem de comentar.
1 Response to “Deixando seu código mais legível”
Sorry, comments are closed for this article.

December 9th, 2008 at 03:55 PM Ótimo post! Sempre me interessei bastante pela boa aparência do código, com o objetivo de torná-lo o mais comunicável possível. Quando você trabalha em equipe e todos seguem o mesmo padrão de formatação de código, isso também ajuda bastante criando uma identidade do "time" e não apenas de um individuo; o que, certamente, facilita bastante na hora de ler/editar código que outra pessoa escreveu.