Não sou uma pessoa supersticiosa, mas hoje é sexta-feira (13) e é melhor não abusar, então vamos manter a tradição e comentar sobre mais um rubismo, ou se preferir, mais uma boa prática de programação que todos os desenvolvedores deveriam adotar independente da linguagem que usem.
Dar nomes para classes, módulos, métodos e variáveis é uma tarefa complicada em alguns casos. Com certeza você em algum momento de sua carreira já ficou na dúvida sobre que nome dar a um determinado método ou variável. Talvez até mesmo apelou para algum colega de trabalho em busca de alguma sugestão.
A regra é: o nome de uma classe, módulo, método ou variável deve ser o mais óbvio possível. Em muitos casos, um programador totalmente concentrado no código que está escrevendo não se apercebe de que o que lhe parece óbvio naquele momento, não será tão óbvio na segunda-feira, depois de um fim de semana com a família. E se ele próprio pode ficar um pouco perdido com nomes estranhos e abreviações, imagine quando um outro programador sem o contexto necessário for fazer uma manutenção naquele código.

Óbvio, mas sem exageros... hehe
Andy Lester em 2004 escreveu em seu artigo “The world’s two worst variable names”, que o pior nome para se dar a uma variável é data. Como no exemplo abaixo:
data = User.find(10)
puts "Nome: = "
Eu já vi muito este tipo de coisa, e tenho certeza de que você também. Mas que droga de nome é este? É óbvio que o que está armazenado em uma variável é um dado (data), mas que tipo de dado, é a pergunta a ser feita. Neste caso especifico renomear a variável para user já faria uma enorme diferença. Nomes como data, ret e temp não querem dizer nada.
Agora vem a melhor (ironicamente) parte, o segundo pior nome para se dar a uma variável é data2 e suas variações. Veja só que coisa horrível:
user = User.find(10)
user2 = User.find(20)
puts "O é amigo do "
No exemplo acima estou usando um nome descritivo, mas qual é a diferença entre user e user2? Eu preciso ser mais óbvio que isto. No contexto do exemplo acima, alterar a segunda variável para friend, resolveria este problema e tornaria meu código mais descritivo.
Não use abreviações
Não use abreviações, à menos que elas sejam realmente óbvias. E quando eu digo óbvia estou dizendo que deve ser para qualquer um, mesmo alguém que nunca trabalhou em seu código. Não existe problema algum em usar nomes longos e descritivos. Veja por exemplo, o nome deste método:
# devolve alguma coisa
end
E então? O que este método faz? Para mim parece óbvio, mas você não tem obrigação de saber que ‘thera’ é uma abreviação para therapeutic, assim como ‘fmt’ é para formatted. Não seria melhor se este método se chamasse formatted_therapeutic_class_code?
No próprio Rails podemos encontrar alguns nomes longos e descritivos como convert_number_column_value e class_name_of_active_record_descendant. Em alguns casos nem precisamos olhar a documentação para entender como o método funciona.
Prefixos não são necessários
Prefixos como str, int e coisas do gênero não são necessários se eu der um nome descritivo à variável. Ao ver uma variável chamada age (idade) logo você deduz que ela deve ser do tipo numérica, assim não seria necessário dar a ela um nome estranho como int_age, ou algo parecido. Podemos dizer o mesmo de uma variável chamada name (nome) que obviamente deve ser um objeto do tipo string.
Use os recursos da linguagem
No Ruby também usamos alguns símbolos em nomes de métodos, como ‘?’ e ‘!’. Um símbolo de interrogação (?) no final no nome indica que aquele método deve retorna um booleano true ou false. O sinal de exclamação (!) informa que o método é destrutivo perigoso, o que pode significar duas coisas: no caso de algo dar errado ele devolverá uma exceção ao invés de um simples false, como nos métodos save e save! do Active Record ou que ele alterará a própria instância do objeto, ao invés de devolver uma nova instância, como nos métodos merge e merge!, por exemplo.
Código bilingue?
Embora não exista uma regra escrita para isto, também sou contra nomear variáveis, métodos ou classe em português. Acho que como todo o código já está em inglês, graças as palavras chaves do Ruby, devemos manter absolutamente tudo em inglês também. Isto não é tão difícil assim, já que você pode fazer uso de tradutores e dicionários (online) para encontrar a melhor descrição para eles.
Pense antes de escolher um nome
Algumas vezes, escolher um bom nome pode parecer difícil, e isto pode acabar roubando um pouco do seu tempo. A dica é que você termine de codificar o seu método primeiro, e depois com o contexto formado em sua mente ficará mais fácil dar um nome descritivo para o método e para as variáveis usadas. Se mesmo assim você ficar na dúvida, inclua um comentário com um TODO no seu código, vá tomar um café e quando você voltar com certeza encontrará um bom nome.
Uma das grandes vantagens que encontramos no Ruby e no Rails é que em ambos é extremamente normal encontrar nomes descritivos e tão curtos quanto possível em classe, módulo, métodos e variáveis. POR FAVOR, NÃO ESTRAGUE ISTO.
Parabéns, ótimo artigo! Sempre senti na pele o que significa ter que conviver com identificadores crípticos. Fui desenvolvedor ABAP, linguagem para desenvolvimento de programas dentro do SAP. Os nomes de colunas e tabelas são todas abreviaturas de palavras em alemão! Até descobrir que VBELN era o número da fatura, demorou um tempo,viu?
Espero que todos se conscientizem da importância desta prática.
Só uma observação, segundo Matz os métodos com sinal de exclamação (!) não indicam necessariamente que este é destrutivo. Indica que este é mais “perigoso” do que o método equivalente sem a exclamação.
David Black também chama a atenção para não escrever métodos com exclamação sem a versão normal.
http://www.wobblini.net/bang.txt
http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist
Algo que ajuda muito para escolher bons nomes de atributos/métodos/classes/módulos é a equipe utilizar a idéia de Ubiquitous Language (http://domaindrivendesign.org/discussion/messageboardarchive/UbiquitousLanguage.html)
E como você comentou, independente de Ruby/Python/Java/X escolher bem os nomes é muito importante, principalmente praquele cara que vai dar manutenção no seu sistema, daqui uns 5 anos :D
Philipe,
Obrigado pelo esclarecimento! Você tem razão.
Rafael, nem precisa ser 5 anos. Amanhã já ninguém lembrará mais o que foi feito.
Concordo com as idéias gerais, mas discordo da forma como o texto faz parecer que é tudo preto no branco.
“Óbvio” é um conceito extremamente relativo. Depende muito do contexto no qual está inserido e da bagagem cultural de cada um. Por exemplo, NÃO é óbvio que uma variável “name” é String; em certos contextos do próprio Ruby um nome pode ser um Symbol (e o pior: há vários cantos no Rails onde só é aceito um tipo particular, sem documentação de qual usar. É testar e ver qual funciona). Em outras situações, poderia ser um objeto especial com atributos para primeiro nome, último nome, e por aí vai. Idem “age”: talvez seja um inteiro, talvez ponto flutuante… não que seja realmente necessário aplicar prefixos nessas situações, mas dizer que o tipo é sempre óbvio também é demais.
(PS: Como o Philipe já disse, “!” não é necessariamente destrutivo… o primeiro exemplo que você deu no artigo já não é destrutivo!)
@Arthur: por acreditar que você está se referindo ao save e save!, sou obrigado a discordar de você: save! é destrutivo, sim. Imagine: você esquece de colocar um “WHERE id=x” no “UPDATE orders SET paid=1″ e manda um save!. Assumindo que o seu código não possui erros de sintaxe ou geradores de exceções, ele rodará sem problemas e marcará todas as suas compras como pagas…
Se isso não for destruição, por favor eu quero uma conta bancária igual a sua. :-)
Abraço
Arthur, nada neste mundo é preto no branco.
Programar sempre vai envolver um contexto. Uma variável chamada name só representa algo dentro de um contexto. Caso contrário ela seria o nome de que?
Quanto ao tipo da variável, também depende, claro! Uma variável age poderia ser um string com o texto “22 anos”, assim como o nome poderia ser um objeto do tipo Name (estranho, mas poderia). Mas nestes casos isto seria uma exceção. E se for o caso, você poderia escolher nomes melhores para isto do que str_age ou obj_name, talvez um nome mais descritivo, se for necessário. Mas isto não muda o fato de que uma variável chamada ‘name’ em 80% DOS CASOS é um objeto do tipo string e uma variável chamada age também quase sempre é um inteiro. Quando isto não for óbvio, talvez seja necessário ser mais descritivo.
E com respeito ao uso do termo ‘destrutivo’, conforme você pode ver em um comentário meu logo acima, eu concordo com o Philipe, talvez o nome ‘destrutivo’ seja forte demais (tanto que alterei no artigo para ‘perigoso’), mas é desta forma que ele é chamado em inglês. Mas eu concordo que o termo não está bem certo.
Obrigado por seu comentário, ele ajudou a esclarecer algumas coisas :)
Uma outra coisa que sempre me irritou no mundo Ruby foram os exemplos de blocos.
Exemplificando…
Porque usar:
@users.collect { |x| x.active }Se você pode usar:
@users.collect { |user| user.active }Ou ainda..
Porque usar:
{1 => {:name => 'Marcos'}, 2 => {:name => 'Carlos'}}.each do |key,value| u = User.find(key) u.update_attributes(value) endSe você pode usar:
{1 => {:name => 'Marcos'}, 2 => {:name => 'Carlos'}}.each do |user_id,attributes| u = User.find(user_id) u.update_attributes(attributes) endAcho que exemplos (encontrados aos montes no google) como esses mostram que no mundo Ruby bons nomes não são um rubismo!
Um abraço
Tapajós,
Realmente, confesso que eu mesmo tenho falhado neste ponto que você levantou.
Muitas vezes me vi usando algo como:
@users.map { |u| u.name }Mas concordo plenamente que isto não parece bom.
Ótimo artigo, e concordo com quase tudo. Só acho que existem algumas exceções, como por exemplo quando é um trecho de código muito pequeno, usado apenas em um bloco. No exemplo acima:
@users.map { |u| u.name }Acho que chamar a variável de “u” não é problema algum. Já é óbvio pra quem lê que se trata de um user, renomear essa variável não traz muitas vantagens.
De qualquer forma, acho que bom senso deve ser usado acima de tudo – esse nome já está claro o suficiente?
My 2 cents. ;D
Sem dúvida programação bilingue pode ficar um pouco confusa, mas para manter a comunicação com o cliente torna tudo mais fácil. Se o seu cliente chama uma fatura de fatura, creio ser mais simples para a comunicação se o nome da classe refletir como é chamada na vida real.
Tiago,
Infelizmente eu não concordo com você neste caso. Não vejo problema algum em escrever especificações em português com o Rspec, mas escrever todo o resto do código em português e inglês é sempre ruim.
Além de criar uma salada, você terá aberrações como @vendedores.each ou @usuario.save em seu código. A coisa ainda será pior se um dia o seu software fizer sucesso e for vendido para qualquer outra empresa do mundo.
Não acho que isto atrapalhe a comunicação com o cliente, mas se este for o caso é um preço pequeno a se pagar para manter o código limpo e a equipe de desenvolvimento motivada.
Mas é somente a minha opinião.
Eu não concordo com essa questão de não misturar os idiomas no código. Para um domínio pequeno ou que esteja totalmente sob o controle da equipe de desenvolvimento, vá lá. Mas no geral o custo de erros de comunicação e dificuldades futuras de manutenção e compreensão dos requisitos, do domínio e do esquema é muito maior do que qualquer benefício estético para o código que isso possa trazer. Já é difícil atingir um consenso sobre os termos usando apenas um idioma.
E acho que a maioria dos desenvolvedores brasileiros não é tão fluente em Inglês a ponto de trabalhar confortavelmente com um domínio nesse idioma.
Sem contar o risco de gerar um domínio que não faz sentido nem para os nativos de Inglês. Nota fiscal modelada como FiscalNote e coisas do gênero…
A questão do idioma é bem complicada. Muita gente simplesmente não sabe inglês e também não quer aprender. Mas uma coisa eu acho, vai fazer em inglês? Ok, faça em inglês. Quer fazer em português? Ok também. Mas não fique fazendo métodos meio a meio, pegar_value() ou coisas do gênero.
Mas é engraçado, esses tempos estava fazendo um sistema para um cemitério, os termos que eles usam nem sempre é fácil de encontrar em inglês. hehe
Leonardo,
É exatamente isto que quero dizer. Não tem como escrever código totalmente em português em Ruby?
if NotaFiscal.saveVocê está escrevendo inglês/português.
Solução para o inglês/português ??? Aprendam inglês. Discordo do Marcio, acredito que todo bom programador que se preze, deveria ter no mínimo o inglês intermediário, não necessariamente gramática, mas os termos técnicos tem que saber, porque sem isso, fica até complicado as vezes saber qual a finalidade de um método, e com o domínio do inglês até básico você sabe qual a função de um plugin como “Acts_as_authenticated”.
Concordo totalmente com você Vanilton!
Eu também acho que Inglês técnico é fundamental para quem é de TI.
Mas a maior parte dos domínios de aplicações comerciais usa um vocabulário muito mais rico do que o necessário para o Inglês técnico.
Tente ler um artigo em Inglês sobre um assunto com o qual você não tem familiaridade. Você vai perceber que o problema maior não é a gramática, mas o vocabulário específico.
Se os clientes usam os termos em Português, modelar em Inglês só vai dificultar a comunicação e a manutenção no futuro.
Acho que o nome mais dificil de encontrar é de uma migration.
Quando são migrations simples, como uma nova tabela ou um novo atributo é blz.
CreateUsers
AddUsersAdmin ou AddAdminToUser
Porém quando você quer fazer mais que uma simples mudança, adicionar n campos a uma tabela, fazer algum como coisa como update_attributes … ai eu acho que já fica mais complicado encontrar um nome. Tem alguma sugestão para isso?
Thiago,
Fora os exemplos que você citou acima, eu desconheço alguma convenção para nomear migrations. Acho que vai mais pelo bom senso dos programadores mesmo…
Carlos Brando,
Como o espaço aqui seria pequeno, respondi com um post lá no meu blog sobre esse seu ótimo artigo, a questão de código bilingue.
Abração.
Sinceramente,
Concordo com o Thiago, ter um código limpo que principalmente favoreça a comunicação entre a equipe e o cliente é um dos aspectos mais importantes durante o desenvolvimento de software.
Em muitos domínios com toda certeza desenvolver usando português é a melhor forma de se ter um código legível, independente se toda a equipe é fluente em inglês (ou outro idioma).
Definir qual idioma utilizar está intimamente ligada ao domínio do cliente, principalmente se você atentar para princípios como Ubiquitous Language, como já citado pelo Rafael Mueller.
Se no final das contas você (e sua equipe) se comunica com o cliente em português então nada melhor que desenvolver/modelar em português (levando em consideração que os termos/jargões do problema sejam pt-Br). Caso a comunicação em inglês com o cliente não seja problemática então não vejo problemas em usar inglês como idioma.
Partir para rigidez de idioma somente porque Ruby (ou qualquer outra linguagem) está em inglês é algo que eu de longe realmente não concordo.
Abraços e excelente post.
Eu não também prefiro usar nomes em inglês, acho mais fáceis e curtos, mas não vejo tanto problema em usar nomes em português dependendo do cliente, desde que não se misture, como getUsuarios, ou findRegistroPos.. isso sim é horrível.
Um ponto que acho que faltou falar foi sobre o tamanho dos nomes dos métodos, é importante sim que os nomes sejam óbvios, mas para isso, não precisa ser uma frase. não há nada mais tosco que um método chamado (usando um exemplo visto no meu trabalho) consultaUsuariosAdminNaoOperadores(). Ora… se a classe é usuários, não precisa diser isso no método, mas pior que isso, então é muito mais simples e mais flexível algo como consulta($tipo, $operador), onde $tipo é o tipo de usuário (no caso admin), e $operador, é um boolean (no caso, false). O método poderia se chamar find, ou fetchAll, se quisesse manter em inglês, mas como era pra um sistema de uma universidade, achamos melhor usar em português mesmo…
Muito Obrigado. Pra eu que estou começando essa é uma informação muito útil.