Sou imoral por usar um nome de variável que difere de seu tipo apenas pelo caso?

95

Por exemplo, pegue este trecho de código:

var person = new Person();

ou para vocês, Pythonistas:

person = Person()

Sempre me dizem como isso é ruim, mas ainda não vi um exemplo da imoralidade dessas duas linhas de código. Para mim, pessoa é uma Pessoa e tentar dar outro nome a ela é perda de tempo. Suponho que nos dias anteriores ao destaque de sintaxe, isso teria sido um grande negócio. Mas hoje em dia, é muito fácil diferenciar um nome de tipo de um nome de variável. Caramba, é até fácil ver a diferença aqui no SO.

Ou há algo que estou perdendo? Nesse caso, seria útil se você pudesse fornecer um exemplo de código que causa problemas.

Jason Baker
fonte
Sempre me perguntei sobre isso. Boa pergunta!
William Brendel de
18
Chamar uma pessoa de pessoa é simplesmente cruel. O que há de errado com "bob"?
Sam Meldrum de
17
Não vamos esquecer que antes de var havia a beleza zen de Person person = new Person ();
Jamie Ide
1
@Jamie, você está chamando a digitação estática de zen?
orokusaki
Eu gostaria de aprofundar ainda mais esta questão: É indiscutivelmente errado fazer Person Person=new Person();quanto a este assunto? Conforme declarado em The Question, vivemos em tempos de realce de sintaxe e reconhecimento de contexto tão incríveis que meu compilador nunca reclamou que eu fizesse exatamente isso. Eu simplesmente amo minhas variáveis ​​CamelCased - por que então eu não deveria (em situações onde Person Personhá uma instanciação geral e única da classe e nenhum conflito está presente nem é possível)?
Robert Synoradzki

Respostas:

94

Qual é o raciocínio daqueles que dizem que isso é ruim? Eu faço isso toda hora. É a maneira mais simples e expressiva de nomear uma única variável de um tipo. Se você precisava de dois Personobjetos, então você poderia prefixar personcom adjetivos significativos como

fastPerson
slowPerson

caso contrário, apenas

person

está bom para mim.

Andrew Hare
fonte
8
"Qual é o raciocínio daqueles que dizem que isso é ruim?" - Não sei. É por isso que comecei este tópico. :-)
Jason Baker
É claro que você nunca precisou entrar no código de outra pessoa. Eu sei que quando sou chamado para pesquisar algum bug recém-descoberto em um código de vários anos atrás por um programador que há muito tempo deixou a empresa - qualquer coisa que atrapalhe meu crescimento é hora de não consertar o problema. Se um desses obstáculos é tentar descobrir o que é uma instância e o que é uma classe só porque um programador não se deu ao trabalho de dizer "var currentPerson = New Person ();" então isso é tempo inútil, perdido. ... e quando seus clientes estão esperando por uma solução, o tempo é essencial.
David,
3
@David - Você me pegou! Eu sabia que a codificação no vácuo iria surgir mais cedo ou mais tarde :) Sério - acho difícil acreditar que você se enganou por ser incapaz de discernir entre os tipos e suas instâncias com base nesta convenção de nomenclatura.
Andrew Hare,
2
@David - esse deve ser o problema para a ferramenta de análise de código. Além disso, é por isso que existe a convenção de que os tipos começam com letras maiúsculas no Python.
ilya n.
69

Eu uso muito esse padrão em assinaturas de método. Se eu não puder fornecer um nome descritivo alternativo, IMHO, não há nada de errado com isso.

O que há de errado seria se você tivesse dois tipos de pessoa e pessoa, então isso é muito, muito errado.

JoshBerke
fonte
1
"O que há de errado seria se você tivesse dois tipos de pessoa e pessoa, então isso é muito, muito errado." - Isso faz sentido para mim.
Jason Baker
1
Se a sua construção de uma API VB não for capaz de lidar com o código, pois não diferencia maiúsculas de minúsculas.
JoshBerke de
1
Ei, no caso de uma API, você está preocupado com nomes de métodos públicos ou propriedades, não nomes de variáveis, porque estes não serão expostos ao código do cliente. Quanto à pergunta de Jason, eu também uso esse nome o tempo todo. Absolutamente nada de errado com isso.
Frederick The Fool
1
Exatamente meu ponto, Frederick, por que ter dois tipos que diferem apenas no caso base é uma má ideia ;-)
JoshBerke
1
Mesmo que não esteja errado, torna o código mais difícil de ler. A legibilidade também é importante.
J3r3myK
45

Eu o uso o tempo todo para referências temporárias a objetos. Eu evitaria isso como uma praga para tipos de dados primitivos.

Person person = new Person(); // okay

int Int = 42; // pure evil
Bill the Lizard
fonte
Se realmente não houvesse nenhum significado semântico que eu pudesse dar a um primitivo, usaria i ou s, além dos índices de loop, não consigo pensar em nenhum outro cenário.
AnthonyWJones
1
Eu não recomendaria usar i, especialmente se você estiver escrevendo código com um loop. i é quase universalmente considerado um nome de variável de loop.
Jason Baker
3
Acordado. Um nome de variável de uma única letra grita "Sou temporário". Os índices de loop devem ser i, j, k, quaisquer outros devem ser a, b, c, x, y, z ou qualquer outra letra que não possa ser confundida com outra coisa, como le o.
Bill the Lizard
bravo! 42 é demais. :)
Vishal Seth
18

Se alguém disser que isso é mau, pergunte se isso é melhor:

var abc = new Person();
Chris
fonte
2
@Chris: exatamente! Ou melhor ainda: var temp = new Person();(Isenção de responsabilidade: eu sei que realmente há lugares para usar variáveis ​​temporárias uma vez, mas, muitas vezes, quando vejo isso no código de alguém, o autor simplesmente nunca voltou a dar a var um nome apropriado e pode bem como "abc".)
Diná,
15

Se a pessoa for uma pessoa geral no contexto, então "pessoa" é um nome realmente bom. Obviamente, se a pessoa tiver uma função específica no código, é melhor nomeá-la usando a função.

PEZ
fonte
9

Acho que vou ser reprovado por dizer isso, mas ...

Tendo acabado de passar por um século testemunhando assassinatos épicos e ganância, nós, programadores, somos verdadeiramente abençoados se a coisa mais imoral que podemos fazer é nomear uma variável.

Mike Dunlavey
fonte
6
Alternativamente, se as decisões morais que podemos tomar são tão insignificantes, somos amaldiçoados. Não tenho certeza se quero que meu elogio fúnebre se concentre em meu estilo de codificação. Eu gostaria de pelo menos uma menção passageira ao fato de eu ser parte de uma família.
David Thornley
1
@David: Certo novamente. Com meu primeiro neto a caminho, acho que é banal, mas me importo com o tipo de mundo que estamos entregando.
Mike Dunlavey
8

Não acho que seja necessariamente "ruim", mas obviamente se você puder qualificá-lo para dar mais contexto, como que tipo de pessoa é (você está lidando com apenas uma das presumivelmente muitas pessoas possíveis), então outra pessoa escolherá pode entender melhor.

Tim Almond
fonte
6

Jason - Não sei quem te disse que isso é ruim. Vários autores usam isso como uma forma padrão de expressar uma instância (minúsculas) de uma classe (maiúscula).

Eu uso isso com bastante frequência, pois descubro que a variável em minúsculas realmente me comunica não apenas que se trata de uma instância, mas também do nome da classe.

A menos que alguém tenha um argumento sólido em contrário, certamente continuarei fazendo isso.

Mark Brittingham
fonte
6

O motivo pelo qual é considerado ruim é que se você precisar ter 2 Person no futuro, poderá acabar com um código semelhante a.

Pessoa pessoa = nova pessoa ();

Pessoa pessoa2 = nova Pessoa ();

Isso seria beirando o "Ruim". No entanto, nesse caso, você deve refatorar sua pessoa original para distinguir entre os dois.

Quanto ao seu exemplo, o nome da variável "pessoa" é um nome perfeitamente descritivo para o objeto "Pessoa". Portanto, não há nada de errado com isso.

Robin Day
fonte
3

Eu digo o que é: se a variável representa uma pessoa com 2 cachorros, chame personWith2Dogs. Se a variável tiver um escopo curto (como um loop var), a pessoa está bem.

Trigo mitch
fonte
3

Eu uso muito isso no meu código e não acho que haja algo de errado com isso. Dito isso, eu (provavelmente) não o usaria em um método mais longo do que, digamos, uma tela, e se houver várias instâncias da classe Person. Definitivamente, não os nomeie pessoa1, pessoa2, pessoa3 ... em vez disso, use algo mais descritivo, como pessoa_para_del, pessoa_para_ban, pessoa_para_atualizar, etc.

kmelvn
fonte
3

Não é imoral, mas uma pesquisa global encontrará ambos Persone personse você não conseguir ativar a diferenciação entre maiúsculas e minúsculas. Eu prefiro um prefixo para tornar a busca / substituição global mais fácil, mas absolutamente NÃO Húngaro ou algo longo / complicado. Então, eu uso ...

Personpara a classe / tipo aPersonpara uma variável local thePersonpara um parâmetro de método myPersonpara uma variável de instância ourPerson para uma variável de classe

Em raras ocasiões, posso usar pem um contexto local onde tenho MUITAS referências, mas isso geralmente se aplica apenas a índices de loop e semelhantes.

Rob Williams
fonte
3

Depende.

Se você tem um estilo de capitalização estrita, então as variáveis ​​começam em minúsculas (e usam under_scores ou camelCase para quebras de palavras) e Classes começam com Letras Maiúsculas, então é óbvio que pessoa é uma variável e Pessoa é uma classe, e quando alguém entende isso , eles não parecerão estar em namespaces sobrepostos. (Da mesma forma, as pessoas quase nunca se confundem entre o verbo ou substantivo "polir" e o adjetivo "polonês".)

Se você não tiver esse estilo, terá dois nomes que podem ser facilmente confundidos e diferem apenas no caso. Isso é ruim.

David Thornley
fonte
Oi de novo David. Não me lembro se foi você quem editou uma das minhas postagens porque eu tinha escrito "polir", ou era "polir", quando pretendia esfregar algo até que brilhasse? Bem, ainda não tenho certeza do que é certo :-)
Mike Dunlavey
Não acho que fiz tal edição, então provavelmente foi outra pessoa. BTW, é "polonês".
David Thornley
2

Quais são os argumentos exatos que essas pessoas usam?

Se eles não permitirem que você use pessoa como um nome de variável, você pode considerar adicionar o prefixo 'a'.

aPerson = Person()
Gerrie Schenck
fonte
2
Isso seria pior, na minha opinião. É mais difícil de ler e não fornece nenhuma informação adicional.
Joachim Sauer de
Sim, mas pelo menos o nome é diferente do nome da classe, que é o que eles querem obviamente.
Gerrie Schenck de
Isso seria seguir as letras da lei, mas definitivamente não o espírito.
Joachim Sauer
1
+1, eu uso thePerson para parâmetros e myPerson para locais que estou gerenciando.
Amy B de
2

Eu acho que o que você está fazendo está bem. Acho que, em geral, é importante ter padrões de codificação acordados.

Por exemplo, eu uso lowerCamelCase para instâncias, variáveis ​​e UpperCamelCase para classes etc.

Os padrões de codificação devem eliminar esse problema.

Quando vejo programas de código aberto bem-sucedidos, eles geralmente têm padrões de codificação

http://drupal.org/coding-standards

http://help.joomla.org/content/view/826/125/

http://wiki.rubyonrails.org/rails/pages/CodingStandards

http://lxr.linux.no/linux/Documentation/CodingStyle

Concordar com os padrões de codificação deve ser a última batalha que você terá sobre isso.

Na verdade, olhe para a entrada da Wikipedia (de http://en.wikipedia.org/wiki/CamelCase )

Estilo de programação e codificação

A capitalização interna às vezes é recomendada para indicar os limites das palavras pelas diretrizes de estilo de codificação para escrever o código-fonte (por exemplo, a linguagem de programação Mesa e a linguagem de programação Java). As recomendações contidas em algumas dessas diretrizes são suportadas por ferramentas de análise estática que verificam a aderência do código-fonte.

Essas recomendações geralmente distinguem entre UpperCamelCase e lowerCamelCase, normalmente especificando qual variedade deve ser usada para tipos específicos de entidades: variáveis, campos de registro, métodos, procedimentos, tipos, etc.

Um estilo de codificação Java amplamente usado determina que UpperCamelCase seja usado para classes, e lowerCamelCase seja usado para instâncias e métodos. [19] Reconhecendo esse uso, alguns IDEs, como o Eclipse, implementam atalhos baseados em CamelCase. Por exemplo, no recurso de assistente de conteúdo do Eclipse, digitar apenas as letras maiúsculas de uma palavra CamelCase irá sugerir qualquer classe ou nome de método correspondente (por exemplo, digitar "NPE" e ativar o assistente de conteúdo pode sugerir "NullPointerException").

A notação húngara original para programação especifica que uma abreviação em minúsculas para o "tipo de uso" (não o tipo de dados) deve prefixar todos os nomes de variáveis, com o restante do nome em UpperCamelCase; como tal, é uma forma de lowerCamelCase. CamelCase é a convenção oficial para nomes de arquivos em Java e para o computador pessoal Amiga.

O Microsoft .NET recomenda lowerCamelCase para parâmetros e campos não públicos e UpperCamelCase (também conhecido como "Estilo Pascal") para outros tipos de identificadores. [20]

Python recomenda UpperCamelCase para nomes de classes. [21]

O registro NIEM requer que os elementos de dados XML usem UpperCamelCase e os atributos XML usem lowerCamelCase.

Não existe uma convenção única para a inclusão de abreviações maiúsculas (principalmente acrônimos e inicialismos) nos nomes CamelCase. As abordagens incluem deixar a abreviatura inteira em maiúsculas (como em "useHTTPConnection") e deixar apenas a primeira letra em maiúsculas (como em "useHttpConnection").

A caixa do camelo não é de forma alguma universal na computação. Os usuários de várias linguagens de programação modernas, notadamente as das famílias Lisp e Forth, quase sempre usam hífens. Entre as razões às vezes dadas estão que fazer isso não exige a troca na maioria dos teclados, que as palavras são mais legíveis quando são separadas e que a caixa de camelo pode simplesmente não ser preservada de forma confiável em linguagens que não diferenciam maiúsculas de minúsculas ou que dobram maiúsculas de minúsculas (como Common Lisp, que, embora seja tecnicamente uma linguagem que diferencia maiúsculas de minúsculas, canoniza (dobra) os identificadores para maiúsculas por padrão).

Stewart Robinson
fonte
2

É possível apresentar um argumento mais forte de que nomes de métodos desse tipo não são apenas inofensivos, mas podem ser um indicador de código de boa qualidade.

  • Um indicador de boa granularidade de código: se seus métodos são curtos, de propósito único e com nomes descritivos, você não precisa de muitas informações em nomes de variáveis. Se você tem métodos longos que fazem muitas coisas e precisam controlar muito o contexto e o estado, os nomes das variáveis ​​precisam ser mais descritivos.

  • Um indicador de cálculos de uso geral sendo empurrados para métodos de uso geral: se você fizer uma manipulação intermediária de estruturas de dados em um método de negócios, por exemplo, uma matriz de usuários deve ser desduplicada, você terá que ter variáveis ​​no escopo com nomes como users[]e deduplicatedUsers[]. Se você mover a desduplicação para um método utilitário, você pode chamar o método Utils.dedup(array)e pode chamar a matriz desduplicada deduplicatedArrayou apenas result.

  • Os descompiladores Java costumam usar um esquema como esse para nomear variáveis ​​locais (as variáveis ​​de instância e classe estão normalmente disponíveis no bytecode, mas as variáveis ​​locais não), e os resultados são mais legíveis do que você poderia esperar, na verdade, muitas vezes mais legíveis do que o fonte original.

  • Veja o princípio de Larry Wall de "Local Ambiguity is OK" - http://www.wall.org/~larry/natural.html .

user8599
fonte
2

Eu diria que você provavelmente tem algum uso específico em mente sempre que cria um objeto. O tipo sozinho raramente reflete esse uso.

Portanto, se você deseja criar um novo contato em seu aplicativo de catálogo de endereços, convém chamar a variável newContact.

E se você estiver testando a unidade de seu código para verificar o comportamento de Personobjetos sem nenhum conjunto de nomes, convém chamá-los unnamedPersonou algo semelhante.

Chamá-lo simplesmente persondispensa uma grande chance de tornar seu código autodocumentado.

Joachim Sauer
fonte
Chame de anônimo! :)) var anonymous = new Person (); Ou ainda melhor: var you_know_who = new Person (); :))
Vadim Ferderer
@Vadim Ferderer var he_who_must_not_be_named = new Person();:? :-)
Platinum Azure
2

Só se você estiver programando em VB6. Nesse caso , o que você está fazendo é ilegal, mas não imoral.

brianegge
fonte
1

Eu também faço isso e também não entendo por que deveria ser 'imoral'. Embora eu possa entender que 'pode' às vezes ser confuso, mas hoje temos IDEs com IntelliSense e realce de sintaxe que irão garantir que (se você cometer um erro e referenciar sua variável em vez de sua classe, e vice-versa), você veja seu erro bem rápido. E também temos o compilador. :)

Frederik Gheysels
fonte
1

Eu também não vejo nenhum problema com essa prática. Contanto que haja apenas uma variável dessa classe, é fácil escrever e ler. Imo, que até se aplica a um editor de texto básico. Eu pessoalmente não consigo me lembrar de ninguém chamando isso de ruim ou mesmo imoral. Continue fazendo isso :)

mafu
fonte
1

Acho que a 'regra' em que você pode estar pensando se destina mais a tipos primitivos e classes em que o nome da classe é um nome de variável pobre.

Por exemplo, se você estivesse lidando com o cálculo do custo de um determinado item em uma loja online, o seguinte código não seria adequado:

Decimal _decimal = item.BaseCost + item.Tax;

Em vez disso, um nome mais descritivo seria recomendado, como '_total' ou '_cost'.

Jay S
fonte
1

O único problema que encontrei com esse tipo de coisa é se você quer o mesmo nome para um membro privado e também para uma propriedade pública.

Se eles diferirem apenas no caso, funcionará bem em linguagens que diferenciam maiúsculas de minúsculas, como C #, mas não em VB.NET.

Então, por exemplo, em VB, eu escreveria

Private _name As String

mas

Public Property Name() As String
    Get
        Return _name
    End Get
    Set(ByVal Value As String)
        _name = Value
    End Set
End Property

Eu faria o mesmo em C #, para que a tradução de um para o outro seja indolor. Também o torna um pouco menos sujeito a erros, já que é muito fácil ler incorretamente ou, na verdade, digitar incorretamente palavras que diferem apenas pelo caso.

ChrisA
fonte
A única coisa que não gosto nessa abordagem é que as variáveis ​​prefixadas com um único sublinhado tendem a ser associadas a membros privados de uma classe. Mas suponho que a abordagem geral seja decente.
Jason Baker de
Sim, é isso que estou ilustrando aqui. Definir uma variável local, como 'Dim person as New Person' seria ótimo. Muito (muito) ocasionalmente com o compilador VB, há uma ambigüidade, e a autocapitalização normal tranquilizadora não acontece. É uma boa dica visual de que nem tudo está bem.
ChrisA de
1

Não é imoral, mas se o seu melhor nome para a sua variável for o nome do tipo, algo errado ou você está apenas fazendo uma prova de conceito ou algo parecido. Para mim, um nome de variável deve se referir ao significado no contexto de negócios e não à linguagem de programação. Será mais difícil entender o código.

João cintra
fonte
1

Costumo usar a Person person = new Person()mim mesmo. Normalmente usado em Java / C #.

Embora eu tenha acabado me perguntando ontem por que

private enum DataType {NEW, OLD}

não funciona em C # ...

Especialmente vendo como você pode usar String, string, Double, double, ... à vontade em C #.

Carra
fonte
enum oferece suporte apenas a byte, sbyte, short, ushort, int, uint, long, ulong. ou seja, tipos de valor numérico não fracionário
Kev
1
Person person = new Person()

está bem no meu livro.

O que fica horrível é quando você tem:

string Person;
string person;

Muito fácil de misturar os 2.

Johnno Nolan
fonte
1

O que foi dito para mim, além de não atender aos nossos Padrões de Codificação, é evitar adicionar confusão quando alguém está lendo meu código. Eu, pessoalmente, não vejo problema nisso, desde que o significado seja claro.

Quanto aos tipos CLR (int, string, etc.), você pode usar String ou string (etc.) para declarar o tipo, portanto, evito usar algo como

int Int = 0;
string String = "hi there";
Muad'Dib
fonte
1

Fazer a capitalização a única diferença é perigoso ... continue fazendo isso para um grande projeto e eu garanto que você encontrará erros bizarros que parece não conseguir localizar.

fastPerson / slowPerson como acima são bons ... eles são descritivos e diferenciados do nome do tipo de variável ... mas vamos lá cara, chamar um int de "Int" seria simplesmente preguiçoso.

alexwood
fonte
1

Eu diria que nunca é imoral - na verdade, é apenas o nome de sua variável de linha de base. Se você não consegue pensar em um nome melhor, nomeá-lo após seu tipo é um bom padrão. ( Apenas para tipos complexos - para tipos integrados é ruim ) E muitas vezes não há um nome melhor porque você não Não sei mais nada sobre a variável. Como com este método

void SaveToDatabase(Person person) {...}

Praticamente a única coisa que você poderia razoavelmente chamar de pessoa é person_to_saveou algo assim que parece redundante.

No entanto, em muitos casos, você pode melhorar a legibilidade de seu código substituindo pessoa por um nome mais descritivo. Por exemplo, isso é menos descritivo

void AddToAccount(Account account, Person person)  {...}

do que isso

void AddToAccount(Account account, Person dependent)  {...}

No entanto, por favor, por favor, não coloque um 'a' ou 't' antes do nome do tipo. Por exemplo, aPerson para 'uma pessoa' ou tPerson para 'a pessoa'. É muito complicado e não agrega muito ou nenhum valor. Além disso, você começa a poluir seu escopo com um monte de variáveis ​​que começam com a ou t que podem minimizar o valor do intelli-sense.

Josué
fonte
Eu concordo com o último parágrafo. Não vejo razão para adicionar personagens estranhos apenas para evitar um pequeno problema de estilo.
Jason Baker
0

Eu não diria que é horrível. Eu geralmente prefixo o nome da variável com 'a' neste tipo de coisa para mostrar que é uma única instância do tipo, então eu faria

Person aPerson = new Person();

Isso torna a leitura do código mais natural, eu acho.

Rob K
fonte
0

Absolutamente nada de errado com isso sujeito a advertências apontadas por outros (resumindo aqui por conveniência): não fazer isso com tipos primitivos, refatorar a instância original se outra instância for adicionada posteriormente, não usar char-case para diferenciar nomes de classe, etc.

Minha regra de ouro? As instruções no código devem ser lidas como frases simples em inglês.

Pessoa pessoa = nova pessoa ();

Funcionário funcionário = person.getRole (EMPLOYEE);

Parent parent = person.getRole (PARENT);

person.getFullName ();

Employee.getSalary ();

parent.getChildren ();

parent.getFullName (); // assumindo o padrão do decorador em jogo

if (person.hasRole (EMPLOYEE)) {

  ...

}

E assim por diante.

Se o escopo da variável for limitado (o método de encapsulamento é de 10-15 linhas, por exemplo), posso até usar 'p' em vez de 'pessoa'. Nomes de variáveis ​​mais curtos são menos distração ao tentar manter o contexto em sua cabeça. Evite prefixos gratuitos, como a notação húngara 'a' ou (tremor) e seus derivados. (Lembre-se de que não tenho nada contra esses prefixos quando usados ​​no contexto apropriado - código C ++ / COM / ATL / API Win32 etc., onde ajuda a manter as atribuições / typecasting corretas).

Meus dois (!) Bits :-)

alan-p
fonte