Usando caracteres únicos para nomes de variáveis em loops / exceções [duplicado]

65

Eu tive algumas discussões com um colega de trabalho sobre o uso de nomes de variáveis de letras únicas em determinadas circunstâncias dentro de nossa base de código, na qual ambos discordamos.

Ele favorece uma convenção de nomenclatura mais detalhada para eles, e eu não.

Na minha opinião, existem três cenários em que uso nomes de variáveis de letras únicas:

  • Loops - i for(int i = 0; i < 10; i++) { ... }
  • Expressões lambda em C # - x/y/z : .Where(x => x == 5)
  • Exceções - e : try { ... } catch(ExceptionType e) { /* usage of 'e' */ }

Estes são os cenários somente em que eu usaria, e obviamente uso mais convenções de nomenclatura mais detalhadas em outros lugares.

Meu colega apresentou os seguintes argumentos para exceções e loops:

  • i - não significa nada.
  • e - é a letra mais comum no idioma inglês. Se você quisesse procurar exceções na solução, encontraria muitas instâncias indesejadas de e .

Eu aceito esses argumentos, mas respondo que, se alguém não sabe o que i significa em um loop for, então eles provavelmente não devem ser um programador. É um termo muito comum para loops e exceções, como é o e . Eu também mencionei que, se alguém quisesse, eles poderiam procurar por catch no caso da exceção.

Eu percebo que isso é subjetivo, mas, então, pode-se argumentar que padrões de codificação são apenas isso - opiniões, embora opiniões de acadêmicos.

Eu ficaria feliz de qualquer forma, e encaminharei os resultados para ele, mas preferiria que nós (nossa empresa) continuássemos a usar um único padrão de codificação, em vez de ter dois desenvolvedores com opiniões diferentes sobre o que usar.

    
por Dan Atkinson 27.04.2011 / 19:15
fonte

20 respostas

79

Concordo inteiramente com a sua opinião e acredito que não é tudo que é subjetivo.

O nome de uma variável é tão relevante quanto seu escopo.

Não há nenhum ponto em discussões intermináveis sobre um nome de uma variável que só será lida por uma pessoa lendo aquele pequeno pedaço de código específico. Por outro lado, nomes de classes e nomes de membros precisam indicar claramente o que está acontecendo. Muito do comportamento esperado precisa ser explicado em um nome conciso.

As convenções melhoram a legibilidade.

i e e são convenções comuns usadas para essas pequenas variáveis de escopo. Sua intenção é realmente clara se você conhece a convenção.

A concisão melhora a legibilidade.

Um nome curto de variável que representa sua intenção é claramente preferível a um nome grande de variável.

    
por 27.04.2011 / 12:52
fonte
54

Isso realmente depende da situação / contexto (e não existe uma solução um serve para todos ).

Em geral, i, j, k [btw, i pode ser considerado índice ; seu uso vem do background matemático, onde esses eram os três primeiros índices (lembre-se do cálculo do tensor). Ele também pode ser conectado ao histórico do Fortran, onde i sendo o primeiro inteiro digitado implicitamente, era frequentemente usado como um índice de um loop. ] são freqüentemente usados se for um simples contador. Se tiver um significado específico, como mês ou ano , o nome da variável mais longo será melhor.

    
por 27.04.2011 / 18:19
fonte
21

Concordo com você: i como um nome de variável de loop é uma expressão antiga que não deve confundir ninguém. O mesmo que e para uma variável de exceção em um bloco catch. Este último (ou melhor, ambos) deve ser curto e simples, tornando pequeno o escopo da variável, limitando a possibilidade de confusão para os leitores. E se alguém quiser procurar exceções, procure por tipos de exceção ou bloqueie de qualquer maneira.

Dito isso, eu pessoalmente prefiro usar nomes de variáveis de loop mais longos, como index ou idx . Meu motivo é que i é tão curto que é difícil localizar com o cursor.

Atualizar

Para referência, os argumentos do seu colega de trabalho provavelmente vêm de Regras do Ottinger para Naming - uma abordagem excelente e pragmática para o assunto, recomendado para leitura. No entanto, ele pode ter negligenciado as partes citadas abaixo:

My personal preference is that single-letter names can ONLY be used as local variables inside short methods. The length of a name should somehow correspond to the size of its scope. If a variable or constant might be seen or used in multiple places in a body of code it is imperative to give it a search-friendly name.

e

Certainly a loop counter may be named i or j or k (though never l!) if its scope is very, very small and no other names can conflict with it. These are allowable because those are traditional solution-domain names.

    
por 18.05.2011 / 09:36
fonte
15

nomes mais detalhados podem ser tão sem sentido. "i" é tão comumente usado como um simples contador de iteração, é uma prática quase comum. Chamar o mesmo contador "iter" porque algum "padrão de codificação" proíbe nomes de variáveis de letras únicas não agrega qualquer valor.

"x", "y" e "z" são nomes de coordenadas padrão, chamando-os de xCoord, yCoord, zCoord não adiciona nada.

"e", claro, é uma expressão matemática. Mas é relativamente comum usá-lo como um nome para exceções em blocos catch em Java. Chamar de "exc" ou algo similar não acrescentaria mais valor real.

    
por 27.04.2011 / 12:28
fonte
15

Eu prefiro nomes de variáveis significativos, mesmo para variáveis de loop. Então, eu costumo escrever algo como

for (int vertexIndex=0; vertexIndex<polygon.VertexCount; vertexIndex++)
   DoSomethingWithVertex(polygon[vertexIndex]);

Eu percebo que há pouca diferença (de qualquer forma) para um pequeno loop como este, mas:

  • se o corpo do loop for maior, vertexIndex é geralmente mais claro que i . É claro que i é um índice, mas qual índice? Para qual array? Para qual elemento nessa matriz?
  • se o corpo do loop chamar outras funções e passar o índice como um argumento, geralmente será mais fácil nomear o valor consistentemente no chamador e nos locais de chamada - e você não desejará chamar os parâmetros de método i and x
  • se houver loops aninhados, usar i , j , k como índices é muito confuso e propenso a erros

para ser consistente, eu apenas uso nomes de variáveis significativos para índices de loop em todos os lugares.

@ André Paramés perguntou: "Se o corpo do loop é longo o suficiente para esconder o significado de i, não é hora de refatorar?"

Um cérebro humano típico tem uma capacidade de memória de curto prazo de cerca de 7 pedaços de dados. Então, se o corpo do loop contém 8 ou mais partes (onde "pedaços" são instruções, variáveis locais, parâmetros, comentários), então seu cérebro não pode armazenar o significado de cada um desses pedaços simultaneamente. Em vez disso, o seu cérebro irá deslocar pedaços dentro e fora da memória de trabalho enquanto você lê o código. Por exemplo, se você usar nomes de variáveis como i e j , seu cérebro mudará os significados de i e j de sua memória de trabalho; da próxima vez que você ler j , seu cérebro normalmente irá depender do contexto para encontrar o significado, ou seja, se você ler customers[j] no meio do corpo do laço, seu cérebro irá inferir que j é um índice na matriz customers . Se você tivesse escrito customers[vertexIndex] , veria que está usando o índice errado. E isso é para corpos de loop muito curtos com apenas 8 blocos de informações, ou seja, 5-8 linhas de código.

Se o corpo ficar mais longo, você normalmente o extrairia em uma função separada com um parâmetro vertexIndex . E esse é o segundo ponto que eu estava fazendo: se a variável é chamada vertexIndex dentro dessa função, ela deve realmente ser chamada de vertexIndex no chamador também.

    
por 28.04.2011 / 15:24
fonte
10

Eu não concordo com os pontos de seus colegas.

Para mim, eu quero dizer "iteração". Bastante significativo no caso de um loop.

A maioria dos IDE permite pesquisas do tipo regex através do texto. Então você poderia procurar por 'e' não dentro de uma palavra. Isso seria eficaz.

    
por 27.04.2011 / 12:19
fonte
6

(Isso é centrado no .NET, mas sua pergunta mencionou expressões C # lambda, então acho que isso é relevante no seu caso.)

Eu sempre usaria ex para uma exceção, pois e já é usado (pelas convenções WinForms e ASP.NET WebForms) como o argumento EventArgs -typed para um manipulador de eventos.

por exemplo,

protected void button_Click(object sender, System.EventArgs e)
{
    try
    {
        // whatever
    }
    catch (Exception ex)
    {
        // some exception handling
    }
}

No entanto, o MSDN usa e para variáveis de exceção .

Durante esta discussão, sugiro manter duas coisas em mente:

  • As convenções de nomenclatura variável geralmente podem ser consideradas uma forma de guerra religiosa .
  • A convenção de codificação mais importante é manter o estilo do código existente .
por 27.04.2011 / 14:37
fonte
5

Eu não vejo nenhuma pergunta aqui, mas "i", "j" geralmente se referem a coordenadas como "x" e "y" (minha preferência pessoal), eu entendo "e" pode ser muito comum, mas se você está procurando por exceções, basta acessar a pesquisa "Exceção".

o maior problema de usar variáveis de letra única é que você pode ficar confuso com elas, mas se essa variável tiver um escopo limitado, como em um loop ou em um try catch, não vejo problema algum

    
por 27.04.2011 / 12:22
fonte
5

Geralmente não é muito relevante quando você tem um único loop, e eu prefiro usar i ou j para simplificar (e por causa da convenção). Com o loop aninhado, às vezes, uso nomes mais detalhados para reconhecer qual índice se relaciona com o quê. Por exemplo, se eu tiver dois arrays: de datas e quantidades, e eu tiver um loop aninhado iterando primeiro sobre datas e depois sobre quantidades, usaria nomes dateIdx e quantityIdx, para evitar confusão. Eu tive erros no meu código quando escrevi

matrix[i][j] = fun(dates[i], quantities[j]);

mas deveria ter

matrix[i][j] = fun(dates[j], quantities[i]);

Com nomes mais detalhados, eu localizaria facilmente o erro, como

matrix[quantityIdx][dateIdx] = fun(dates[quantityIdx], quantities[dateIdx]);

pareceria errado.

    
por 27.04.2011 / 12:45
fonte
5

Nomes de variáveis curtas são como pronomes em linguagens naturais: para serem usados em um pequeno contexto / escopo. "i" em um loop curto (sem aninhamentos) ou "e" em uma seqüência de algumas capturas são perfeitamente ok. Em muitos casos, o nome longo / descritivo de "i" seria "the_stupid_index_needed_to_get_at_the_really_interesting_things" e você usa uma expressão lambda apenas porque é necessária apenas em um contexto.

Perl's $ _ é um super-pronome que funciona (para programadores Perl); apesar de ser permitido / incentivado a pular mesmo 'it' (apenas "print" para "print $ _") é algo que eu tenho um pouco de medo.

A pesquisa de nomes de variáveis para detectar problemas no código não seria minha primeira ideia. Eu acho que o programador deveria ter uma idéia sobre a classe ou função onde procurar em caso de problemas específicos.

    
por 27.04.2011 / 12:45
fonte
4

Uma questão epistemológica interessante é a de significado . Seu colega parece presumir que só porque algo significa algo para ele , então é significado e caso contrário não é.

A verdade é, claro, que todos os símbolos que estamos usando todos os dias, não apenas na programação, só têm sentido porque os atribuímos a eles. Ou, para colocar de forma diferente, o significado está no seu cérebro, não no símbolo. (Para deixar isso claro para os outros, pense em uma tabuinha cuneiforme - certamente ela teve significado para os escritores uma vez, ainda que para a maioria dos bilhões de pessoas hoje não tenha).

À luz disso, a suposição de que nomes longos significam algo, enquanto nomes curtos não significam, é um absurdo. Além disso, a expectativa de que um nome longo em um texto de programa, de alguma forma, carrega o significado que possivelmente tem em um contexto diferente pode levar à confusão.

    
por 27.04.2011 / 12:52
fonte
4

Alguns pontos:

  • Eu ouvi sugerir que você deveria preferir usar "ii" para "i" porque se você tiver que procurar o seu índice de loop você será capaz de fazê-lo (e é visualmente mais distinto em geral ), e acho que é uma boa ideia.
  • Depende do escopo e do conteúdo do seu loop. Se o seu loop está simplesmente fazendo algo 10 vezes (por exemplo, se ele nem sequer acessa a variável loop), então eu penso que "i" ou "ii" é mil vezes mais razoável que um nome mais longo. Todo mundo que já tenha programado deve saber ou aprender do que "i" normalmente significa "variável de loop"
  • Se o seu loop tiver um bloco de código grande dentro, considere extraindo isso para uma função, mas de qualquer forma, pode ser valioso ter um nome curto mas significativo, por exemplo. carIdx ou dia, não menos importante, porque você pode querer usar "i" dentro do corpo do loop.
  • Se o loop estiver passando sobre o conteúdo de uma estrutura de dados, use um nome relevante: uma abreviação ou letra minúscula do tipo de dado ou variável contida, se for razoavelmente distinta (por exemplo, para carro em carrosOwned) ou um formulário mais longo o seu loop é mais complexo.
  • Acho que o mesmo se aplica a lambdas e exceções, embora eu seja menos familiarizado. Por exemplo, se houver um nome sensato para a entrada para o seu lambda, especialmente se houver mais de um, use-o, mas na maioria das vezes, todo o POINT de um lambda é receber uma entrada anônima, que todos entendem " x "significa muito bem.
por 27.04.2011 / 13:18
fonte
4

Quando falamos de código legível, você tem algumas coisas a considerar:

  • Quais são seus padrões de codificação?
  • Quais são as convenções comuns para sua plataforma?
  • Existe o potencial de confusão?

Supondo que seus padrões de codificação não digam muito sobre convenções de nomenclatura de variáveis, deve-se pensar em discutir o código. Por exemplo, com o loop abaixo:

for(int i = 0; i < 10; i++)
{
    function(i);
}

O loop e todas as suas funções podem ser claramente vistas por todo o seu escopo. Agora, imagine se nós tivermos loops aninhados (o meu favorito é o loop dentro de um loop dentro de um loop); ou talvez um loop que abrange 100 linhas. Nesse ponto, os iteradores de uma única letra não fazem muito sentido, porque é muito fácil se perder no escopo. Você pode querer refatorar essas 100 linhas de código em alguns métodos / funções para domar um pouco, mas dê ao índice um nome significativo.

Com relação a exceções, eu tendia a concordar que e simplesmente não é um bom nome. No entanto, minhas razões são diferentes das do seu amigo. Eu fiz um monte de programação Java ao longo dos anos, e tenho que lidar com todas as exceções verificadas desagradáveis que nunca serão lançadas a menos que alguém hacks sua instalação Java. É um fato da vida. Então, como você está lidando com uma exceção, você tem que encapsular parte de sua manipulação de exceção dentro de outro manipulador de exceção. Um lugar comum que isso ocorre é com o código JDBC.

Resumindo, uma vez que cada exceção que você estava verificando precisa de um nome único, e você está lidando com vários tipos de erros em uma cláusula try, dê a essas exceções nomes que signifiquem alguma coisa. Ver e , e1 , e2 não ajuda quando estou lendo o código. Que tipo de exceção estou olhando? Então, novamente, já que há espaço para confusão, use nomes longos.

    
por 27.04.2011 / 14:23
fonte
3

Eu uso i como um contador em loops apenas quando:

  • é usado como um índice; e
  • quando seu escopo é muito curto.

Como Rook disse, o termo i tem um histórico matemático como um índice que foi marcado como uma convenção de programação. No entanto, se for um loop longo, contendo muitas variáveis, eu renomearia o contador i para algo mais explícito. Se você tiver loops aninhados que iteram, por exemplo, uma matriz, geralmente uso row e col , já que i e j não são exatamente claros sobre o que eles se referem ("Foi A[i][j] ou A[j][i] ...? ").

Em relação a e para exceções, costumo usar ex porque vi e ser usado para element .

    
por 27.04.2011 / 14:55
fonte
2

Tudo se resume à diferença entre "o que você está fazendo?" vs. "Como você está fazendo isso?"

Primeiro, sempre que possível, use um foreach em vez de um for . É melhor expressar o que você está fazendo (ou seja, percorrer a coleção e processar cada elemento). Isso elimina o problema de nomear completamente.

Se a variável index tiver algum significado diferente de "the_stupid_index_needed_to_get_at_the_really_interesting_things" (obrigado E.H.) então use esse significado. row e col devem ser preferidos em relação a i e j se a matriz estiver representando uma tabela. Eu também gosto de usar position ou pos se estou fazendo muita troca.

No entanto, o idioma for (int i = 0 ....) está tão bem estabelecido que é o padrão de fato para uma iteração. Não mexa com o idioma bem estabelecido sem uma boa razão.

Exceção acima: Matemática ou Física - Use as fórmulas padrão do texto.

v = d/t; é mais familiar para um físico ou engenheiro do que velocity = distance / time;

    
por 27.04.2011 / 15:17
fonte
1

Embora eu não tenha nenhum problema em usar "i", os padrões exigentes exigem algo mais. Eu não perderia tempo discutindo se é necessário. Para mim, "loopIndex" e "loopCounter" são dois nomes padrão que eu uso em vez de "i".

    
por 27.04.2011 / 12:50
fonte
1

@ nikie listou alguns dos meus argumentos, mas quero acrescentar que seu argumento para limitar a verbosidade é fraco.

Olhando o código isoladamente, um nome mais descritivo ajudaria. Identificar o loop em si não é um problema como você mencionou.

Você usará o 'i' muitas vezes em um aplicativo e poderá economizar algumas digitações, mas nem todas se referem à mesma coisa. Muitos scripts SQL irão aliasar uma tabela com uma única letra, mas toda vez que ela é usada, ela está se referindo à mesma tabela.

Criar nomes significativos pode ser difícil, e é por isso que é melhor criar um hábito.

    
por 27.04.2011 / 13:38
fonte
1

Eu achei que i significava "incremento". Eu acho que o grande número de respostas diferentes indica que há algo na questão original sobre o significado dos nomes das variáveis - eles geralmente significam algo tradicional, mas muitas pessoas os usam sem saber o que é a tradição. É fácil dizer que alguém que não sabe o que significa i "não deveria ser um programador", mas como você aprende o que significa i ? Há meia dúzia de respostas aqui mesmo.

    
por 27.04.2011 / 17:14
fonte
1

Steve McConnell no Code Complete tinha ótimos conselhos para verbosidade dos nomes das variáveis, tudo depende do escopo e do uso da variável. Se você tem uma classe grande, suas variáveis de membro devem ter nomes claros, já que você quer saber o que a variável representa quando você está enterrado no código na metade do arquivo. Se você tem uma função curta ou uma variável usada apenas para algumas linhas de código, você pode fazer o menor que quiser, pois não ficará confuso sobre onde ela está definida ou o que ela representa, e um nome menor fará o código mais claro.

Portanto, para o seu caso, i, eex são ótimos nomes de variáveis. (assumindo que você não tem grandes loops complexos)

    
por 28.04.2011 / 00:02
fonte
1

Para "e" , que obviamente significa "exceção" ou "erro", é fácil procurar por exceções, você só precisa garantir que sua pesquisa corresponda a palavras inteiras (também pode pesquisar por "e)" com Se você não usar um espaço entre a variável e os parênteses, você não encontrará muitos "e" s, exceto nos manipuladores de exceção.

Para "i" , ele tem um significado: significa "iterador" (ou possivelmente "índice" ou "incrementador").

Há outro motivo para ter um nome de variável curto: atalhos para o que seriam nomes de variáveis / classes mais longos que são usados com muita freqüência em uma estrutura ou o que você tem. Como o JQuery "$" .

    
por 28.04.2011 / 02:25
fonte