¿Soy inmoral por usar un nombre de variable que difiere de su tipo solo por caso?

95

Por ejemplo, tome este fragmento de código:

var person = new Person();

o para ustedes Pythonistas:

person = Person()

Constantemente me dicen lo malo que es esto, pero aún no he visto un ejemplo de la inmoralidad de estas dos líneas de código. Para mí, la persona es una Persona y tratar de darle otro nombre es una pérdida de tiempo. Supongo que en los días previos al resaltado de sintaxis, esto habría sido un gran problema. Pero en estos días, es bastante fácil diferenciar el nombre de un tipo de un nombre de variable. Diablos, incluso es fácil ver la diferencia aquí en SO.

¿O hay algo que me estoy perdiendo? Si es así, sería útil si pudiera proporcionar un ejemplo de código que causa problemas.

Jason Baker
fuente
Siempre me he preguntado sobre esto. ¡Buena pregunta!
William Brendel
18
Llamar a una persona persona es simplemente cruel. ¿Qué pasa con "bob"?
Sam Meldrum
17
No olvidemos que antes de var existía la belleza zen de Person person = new Person ();
Jamie Ide
1
@Jamie, ¿estás llamando a la escritura estática como zen?
orokusaki
Me gustaría profundizar un nivel más en esta pregunta: ¿Es indiscutiblemente incorrecto actuar Person Person=new Person();en este sentido? Como se indica en The Question, vivimos en tiempos de resaltado de sintaxis y reconocimiento de contexto tan increíbles que mi compilador nunca se quejó de que yo hiciera precisamente eso. Me encantan mis variables CamelCased, ¿por qué entonces no debería hacerlo (en situaciones en las que Person Personhay una instancia general y única de la clase y no hay ningún conflicto presente ni posible)?
Robert Synoradzki

Respuestas:

94

¿Cuál es el razonamiento de quienes te dicen que esto es malo? Hago esto todo el tiempo. Es la forma más simple y expresiva de nombrar una sola variable de un tipo. Si necesita dos Personobjetos, puede prefijar personadjetivos significativos como

fastPerson
slowPerson

de lo contrario solo

person

esta bien conmigo.

Andrew Hare
fuente
8
"¿Cuál es el razonamiento de los que te dicen que esto es malo?" - No sé. Por eso comencé este tema. :-)
Jason Baker
Claramente nunca has tenido que entrar en el código de otra persona. Sé que cuando un programador que hace mucho que dejó la empresa me pide que investigue un error recientemente descubierto en un código de hace varios años, cualquier cosa que se interponga en el camino para mejorar es tiempo de no solucionar el problema. Si uno de esos obstáculos es tratar de averiguar qué es una instancia y qué es una clase solo porque un programador no puede molestarse en decir "var currentPerson = New Person ();" entonces eso es tiempo inútil, perdido. ... y cuando sus clientes esperan una solución, el tiempo es fundamental.
David
3
@David - ¡Me atrapaste! Sabía que la codificación en el vacío mostraría su fea cabeza tarde o temprano :) Sin embargo, en serio, me cuesta creer que te tropieces al no poder discernir entre tipos y sus instancias en función de esta convención de nomenclatura.
Andrew Hare
2
@David: ese debería ser el problema para la herramienta de análisis de código. Además, es por eso que existe la convención de que los tipos comienzan con letras mayúsculas en Python.
ilya n.
69

Utilizo mucho este patrón en las firmas de métodos. Si no puedo proporcionar un nombre descriptivo alternativo, en mi humilde opinión, no hay nada de malo en esto.

Lo que está mal sería si tienes dos tipos Persona y persona, entonces eso está muy muy mal.

JoshBerke
fuente
1
"Lo que está mal sería si tienes dos tipos de persona y persona, entonces eso está muy, muy mal". - Esto tiene mucho sentido para mí.
Jason Baker
1
Si está construyendo una API VB no podría manejar el código ya que no distingue entre mayúsculas y minúsculas.
JoshBerke
1
Oye, en el caso de una API, te preocupan los nombres o las propiedades de los métodos públicos, no los nombres de las variables, porque estos últimos no estarán expuestos al código del cliente. En cuanto a la pregunta de Jason, yo también uso este nombre todo el tiempo. Absolutamente no tiene nada de malo.
Frederick The Fool
1
Exactamente mi punto Frederick por qué tener dos tipos que difieren solo en el caso base es una mala idea ;-)
JoshBerke
1
Incluso si no está mal, hace que el código sea más difícil de leer. La legibilidad también importa.
J3r3myK
45

Lo uso todo el tiempo para referencias de objetos temporales. Lo evitaría como la plaga de tipos de datos primitivos.

Person person = new Person(); // okay

int Int = 42; // pure evil
Bill el lagarto
fuente
Si realmente no hubiera un significado semántico, podría dar un primitivo, usaría i o s, aparte de los índices de bucle, no puedo pensar en ningún otro escenario similar.
AnthonyWJones
1
Recomendaría no usar i, especialmente si está escribiendo código con un bucle. i se considera casi universalmente como un nombre de variable de ciclo.
Jason Baker
3
Convenido. Un nombre de variable de una sola letra grita "Soy temporal". Los índices de bucle deben ser i, j, k, los demás deben ser a, b, c, x, y, z, o cualquier otra letra que no pueda confundirse con otra cosa, como lyo.
Bill the Lizard
¡Bravo! 42 es demasiado. :)
Vishal Seth
18

Si alguien dice que eso es malo, pregúntele si es mejor:

var abc = new Person();
Chris
fuente
2
@Chris: ¡exactamente! O mejor aún: var temp = new Person();(Descargo de responsabilidad: sé que realmente hay lugares para usar variables temporales por única vez, pero la mayoría de las veces, cuando veo esto en el código de alguien, el autor simplemente nunca volvió a darle a la var un nombre apropiado y puede también ser "abc".)
Dinah
15

Si la Persona es una Persona general en el contexto, entonces "persona" es un nombre realmente bueno. Por supuesto, si la Persona tiene un rol específico en el código, entonces es mejor nombrarla usando el rol.

PEZ
fuente
9

Supongo que me votarán negativamente por decirlo, pero ...

Habiendo pasado un siglo siendo testigo de asesinatos épicos y codicia, los programadores somos realmente bendecidos si lo más inmoral que podemos hacer es nombrar una variable.

Mike Dunlavey
fuente
6
Alternativamente, si las decisiones morales que podemos tomar son tan insignificantes, estamos malditos. No estoy seguro de querer que mi elogio fúnebre se concentre en mi estilo de programación. Me gustaría al menos una mención de pasada de que soy parte de una familia.
David Thornley
1
@David: Correcto de nuevo. Con mi primer nieto en camino, supongo que es trillado, pero me importa qué tipo de mundo estamos transmitiendo.
Mike Dunlavey
8

No creo que sea necesariamente "malo", pero obviamente si puedes calificarlo para darle más contexto, como qué tipo de persona es (estás tratando con solo una de las muchas personas posibles), entonces alguien más lo elige puede entender mejor.

Tim Almond
fuente
6

Jason: no estoy seguro de quién te ha dicho que esto es malo. Varios autores utilizan esto como una forma estándar de expresar una instancia (minúscula) de una clase (en mayúscula).

Utilizo esto con bastante frecuencia ya que encuentro que la variable en minúsculas en realidad me comunica no solo que se trata de una instancia, sino también el nombre de la clase.

A menos que alguien tenga un argumento sólido en contra, ciertamente continuaré haciendo esto.

Mark Brittingham
fuente
6

La razón por la que se considera malo es que si necesita tener 2 Person's en el futuro, puede terminar con un código similar.

Persona persona = nueva Persona ();

Persona person2 = nueva Persona ();

Eso estaría al borde de "Malo". Sin embargo, en ese caso, debe refactorizar a su persona original para distinguir entre los dos.

Como en su ejemplo, el nombre de variable "persona" es un nombre perfectamente descriptivo para el objeto "Persona". Por lo tanto, no hay nada de malo en ello.

Día de Robin
fuente
3

Digo nombre por lo que es: si la variable representa a una persona con 2 perros, llámala personWith2Dogs. Si la variable tiene un alcance corto (como una var de bucle), la persona está bien.

Trigo Mitch
fuente
3

Lo uso mucho en mi código y no creo que tenga nada de malo. Dicho esto, (probablemente) no lo usaría en un método más largo que, digamos, una pantalla, y si hay varias instancias de la clase Person. Definitivamente no los nombre person1, person2, person3 ... en su lugar use algo más descriptivo, como person_to_del, person_to_ban, person_to_update, etc.

kmelvn
fuente
3

No es inmoral, pero una búsqueda global encontrará ambos Persony personsi no activa la distinción entre mayúsculas y minúsculas. Prefiero un prefijo para facilitar la búsqueda / reemplazo global, pero absolutamente NO húngaro o algo largo / complicado. Entonces, uso ...

Personpara la clase / tipo aPersonpara una variable local thePersonpara un parámetro de método myPersonpara una variable de instancia ourPersonpara una variable de clase

En raras ocasiones, podría usarlo pen un contexto local donde tengo MUCHAS referencias, pero eso generalmente solo se aplica a índices de bucle y similares.

Rob Williams
fuente
3

Depende.

Si tiene un estilo de uso de mayúsculas estricto, por lo que las variables comienzan en minúsculas (y usan under_scores o camelCase para los saltos de palabras), y las clases comienzan con letras mayúsculas, entonces es obvio que person es una variable y Person es una clase, y cuando alguien entienda esto , no parecerán estar en espacios de nombres superpuestos. (Del mismo modo, la gente casi nunca se confunde entre el verbo o sustantivo "polaco" y el adjetivo "polaco").

Si no tiene ese estilo, entonces tiene dos nombres que pueden confundirse fácilmente y difieren solo en mayúsculas y minúsculas. Eso es malo.

David Thornley
fuente
Hola de nuevo David. No recuerdo si fuiste tú quien editó una de mis publicaciones porque había escrito "pollish", o era "polish", cuando quise frotar algo hasta que brille. Bueno, todavía no estoy seguro de cuál es la correcta :-)
Mike Dunlavey
No creo que hice ninguna edición de ese tipo, por lo que probablemente fue otra persona. Por cierto, es "pulido".
David Thornley
2

¿Cuáles son los argumentos exactos que usa esa gente?

Si no le permiten usar person como nombre de variable, podría considerar agregar el prefijo 'a'.

aPerson = Person()
Gerrie Schenck
fuente
2
Eso sería peor, en mi opinión. Es más difícil de leer y no proporciona información adicional alguna.
Joachim Sauer
Sí, pero al menos el nombre es diferente del nombre de la clase, que es lo que obviamente quieren.
Gerrie Schenck
Eso sería seguir las letras de la ley, pero definitivamente no el espíritu.
Joachim Sauer
1
+1, utilizo thePerson para los parámetros y myPerson para los locales que estoy administrando.
Amy B
2

Creo que lo que estás haciendo está bien. Creo que, en general, es importante tener estándares de codificación acordados.

Por ejemplo, uso lowerCamelCase para instancias, variables y UpperCamelCase para clases, etc.

Los estándares de codificación deberían eliminar este problema.

Cuando miro programas de código abierto exitosos, a menudo tienen estándares de codificación

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

Acordar los estándares de codificación debería ser la última batalla que tengas al respecto.

De hecho, mire la entrada de wikipedia (de http://en.wikipedia.org/wiki/CamelCase )

Estilo de programación y codificación

A veces se recomienda utilizar mayúsculas internas para indicar los límites de las palabras según las pautas de estilo de codificación para escribir código fuente (por ejemplo, el lenguaje de programación Mesa y el lenguaje de programación Java). Las recomendaciones contenidas en algunas de estas pautas están respaldadas por herramientas de análisis estático que verifican el cumplimiento del código fuente.

Estas recomendaciones a menudo distinguen entre UpperCamelCase e lowerCamelCase, y suelen especificar qué variedad se debe utilizar para tipos específicos de entidades: variables, campos de registro, métodos, procedimientos, tipos, etc.

Un estilo de codificación de Java ampliamente utilizado dicta que UpperCamelCase se use para clases y lowerCamelCase se use para instancias y métodos. [19] Reconociendo este uso, algunos IDE, como Eclipse, implementan accesos directos basados ​​en CamelCase. Por ejemplo, en la función de asistencia de contenido de Eclipse, escribir solo las letras mayúsculas de una palabra de CamelCase sugerirá cualquier clase o nombre de método coincidente (por ejemplo, escribir "NPE" y activar la asistencia de contenido podría sugerir "NullPointerException").

La notación húngara original para programación especifica que una abreviatura en minúscula para el "tipo de uso" (no el tipo de datos) debe anteponer todos los nombres de las variables, con el resto del nombre en UpperCamelCase; como tal, es una forma de lowerCamelCase. CamelCase es la convención oficial para los nombres de archivos en Java y para la computadora personal Amiga.

Microsoft .NET recomienda lowerCamelCase para parámetros y campos no públicos y UpperCamelCase (también conocido como "Estilo Pascal") para otros tipos de identificadores. [20]

Python recomienda UpperCamelCase para los nombres de clases. [21]

El registro NIEM requiere que los elementos de datos XML utilicen UpperCamelCase y que los atributos XML utilicen lowerCamelCase.

No existe una convención única para la inclusión de abreviaturas en mayúsculas (principalmente acrónimos e iniciales) dentro de los nombres de CamelCase. Los enfoques incluyen dejar toda la abreviatura en mayúsculas (como en "useHTTPConnection") y dejar solo la primera letra en mayúsculas (como en "useHttpConnection").

El caso Camel no es de ninguna manera universal en informática. Los usuarios de varios lenguajes de programación modernos, en particular los de las familias Lisp y Forth, casi siempre usan guiones. Algunas de las razones que se dan a veces son que para hacerlo no es necesario cambiar en la mayoría de los teclados, que las palabras son más legibles cuando están separadas y que el caso camel simplemente puede no conservarse de manera confiable en los lenguajes que no distinguen entre mayúsculas y minúsculas (como Common Lisp, que, aunque técnicamente es un lenguaje que distingue entre mayúsculas y minúsculas, canonicaliza (dobla) los identificadores a mayúsculas de forma predeterminada).

Stewart Robinson
fuente
2

Es posible argumentar con más fuerza que los nombres de métodos de ese tipo no solo son inofensivos, sino que también pueden ser un indicador de código de buena calidad.

  • Un indicador de buena granularidad de código: si sus métodos son cortos, de un solo propósito y con nombres descriptivos, no necesita mucha información en los nombres de las variables. Si tiene métodos largos que hacen muchas cosas y necesita realizar un seguimiento de una gran cantidad de contexto y estado, entonces los nombres de las variables deben ser más descriptivos.

  • Un indicador de que los cálculos de propósito general se reducen a métodos de propósito general: si realiza una manipulación intermedia de las estructuras de datos en un método comercial, por ejemplo, se debe deduplicar una matriz de usuarios, tendrá que tener variables en el alcance con nombres como users[]y deduplicatedUsers[]. Si mueve la deduplicación a un método de utilidad, puede llamar al método Utils.dedup(array)y puede llamar a la matriz deduplicada deduplicatedArrayo simplemente result.

  • Los descompiladores de Java a menudo usan un esquema como ese para nombrar variables locales (las variables de instancia y clase normalmente están disponibles en el código de bytes, pero las variables locales no lo están), y los resultados son más legibles de lo que cabría esperar, de hecho, a menudo más legibles que el fuente original.

  • Vea el principio de Larry Wall de "La ambigüedad local está bien" - http://www.wall.org/~larry/natural.html .

user8599
fuente
2

Yo diría que probablemente tengas en mente algún uso específico cada vez que crees un objeto. El tipo por sí solo rara vez refleja ese uso.

Entonces, si desea crear un nuevo contacto en su aplicación de libreta de direcciones, es posible que desee llamar a la variable newContact.

Y si está probando unitariamente su código para verificar el comportamiento de Personobjetos sin nombres establecidos, es posible que desee llamarlos unnamedPersono algo similar.

Llamarlo simplemente personrenuncia a una gran oportunidad de hacer que su código se auto-documente.

Joachim Sauer
fuente
¡Llámalo anónimo! :)) var anonymous = nueva Persona (); O incluso mejor: var you_know_who = new Person (); :))
Vadim Ferderer
@Vadim Ferderer var he_who_must_not_be_named = new Person();:? :-)
Platinum Azure
2

Solo si está programando en VB6. En ese caso , lo que estás haciendo es ilegal, pero no inmoral.

Brianegge
fuente
1

Yo también lo hago, y tampoco entiendo por qué debería ser 'inmoral'. Aunque puedo entender que 'podría' a veces ser confuso, pero hoy tenemos IDE con intellisense y resaltado de sintaxis que se asegurará de que (si comete un error y hace referencia a su variable en lugar de su clase, y viceversa) vea su error bastante rápido. Y también tenemos el compilador. :)

Frederik Gheysels
fuente
1

Tampoco veo ningún problema con esta práctica. Siempre que haya solo una variable de esa clase, es fácil de escribir y de leer. Imo, eso incluso se aplica en un editor de texto básico. Personalmente, no recuerdo que nadie lo haya llamado malo o incluso inmoral. Solo continúa haciendo esto :)

mafu
fuente
1

Creo que la 'regla' en la que puede estar pensando está destinada más a tipos primitivos y clases donde el nombre de la clase hace un nombre de variable pobre.

Por ejemplo, si estuviera tratando de calcular el costo de un artículo en particular en una tienda en línea, el siguiente código no sería una buena forma:

Decimal _decimal = item.BaseCost + item.Tax;

En su lugar, se recomendaría un nombre más descriptivo, como '_total' o '_cost'.

Jay S
fuente
1

El único problema con este tipo de cosas que he encontrado es si desea el mismo nombre para un miembro privado y también una propiedad pública.

Si estos difieren solo en el caso, funcionará bien en lenguajes que distinguen entre mayúsculas y minúsculas, como C #, pero no en VB.NET.

Entonces, por ejemplo, en VB, escribiría

Private _name As String

pero

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

Haría lo mismo en C #, para que la traducción de uno a otro sea indolora. También lo hace un poco menos propenso a errores, ya que es muy fácil leer mal, o incluso escribir mal, palabras que difieren solo en mayúsculas y minúsculas.

ChrisA
fuente
Lo único que no me gusta de este enfoque es que las variables prefijadas con un solo subrayado tienden a asociarse con miembros privados de una clase. Pero supongo que el enfoque general es decente.
Jason Baker
Sí, esto es lo que estoy ilustrando aquí. Definir una variable local, como 'Persona oscura como persona nueva' estaría bien. Muy (muy) ocasionalmente con el compilador de VB, hay una ambigüedad, y la normalización de mayúsculas automática tranquilizadora no ocurre. Es una buena señal visual de que no todo está bien.
ChrisA
1

No es inmoral, pero si su mejor nombre para su variable es el nombre del tipo, algo anda mal o simplemente está haciendo una prueba de concepto o algo así. Para mí, un nombre de variable debe hacer referencia al significado en el contexto empresarial y no al lenguaje de programación. Será más difícil entender el código.

João Cintra
fuente
1

A menudo Person person = new Person()me uso . De uso común en Java / C #.

Aunque acabé preguntándome ayer por qué

private enum DataType {NEW, OLD}

no funciona en C # ...

Especialmente ver cómo se puede utilizar String, string, Double, double, ... a voluntad en C #.

Carra
fuente
enum solo admite byte, sbyte, short, ushort, int, uint, long, ulong. es decir, tipos de valores numéricos no fraccionarios
Kev
1
Person person = new Person()

está bien en mi libro.

Cuando se vuelve horrible es cuando tienes:

string Person;
string person;

Es muy fácil mezclar los 2.

Johnno Nolan
fuente
1

Lo que se me ha expresado, además de no cumplir con nuestros estándares de codificación, es evitar agregar confusión cuando alguien más está leyendo mi código. Personalmente, no veo ningún problema en ello, siempre que el significado sea claro.

En cuanto a los tipos CLR (int, string, etc.), puede usar String o string (etc.) para declarar el tipo, por lo que evitaría usar algo como

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

Hacer de las mayúsculas la única diferencia es peligroso ... sigue haciendo esto para un gran proyecto y te garantizo que te encontrarás con errores extraños que parece que no puedes localizar.

fastPerson / slowPerson como arriba están bien ... son descriptivos y diferenciados del nombre del tipo de variable ... pero vamos hombre, llamar a un int "Int" sería simplemente perezoso.

Alexwood
fuente
1

Yo diría que nunca es inmoral, en realidad es solo el nombre de la variable de línea base. Si no puede pensar en un nombre mejor, nombrarlo después de su tipo es un buen valor predeterminado ( solo para tipos complejos , para tipos integrados es malo ) Y muchas veces no hay un nombre mejor porque no No sé nada más sobre la variable. Como con este método

void SaveToDatabase(Person person) {...}

Casi lo único más a lo que razonablemente podría llamar persona es person_to_saveo algo así que parece redundante.

Sin embargo, en muchos casos, puede mejorar la legibilidad de su código reemplazando persona con un nombre más descriptivo. Por ejemplo, esto es menos descriptivo

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

que esto

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

Sin embargo, por favor, por favor, no pongas una "a" o "t" delante del nombre del tipo. Es decir, aPerson para 'una persona' o tPerson para 'la persona'. Es demasiado complicado y no aporta mucho valor. Además, comienza a contaminar su alcance con un montón de variables que comienzan con aot que pueden minimizar el valor de intelli-sense.

Josué
fuente
Estoy de acuerdo con el último párrafo. No veo ninguna razón para agregar caracteres extraños solo para evitar un problema menor de estilo.
Jason Baker
0

No diría que es horrible. Por lo general, prefijo el nombre de la variable con 'a' en este tipo de cosas para mostrar que es una instancia única del tipo, por lo que haría

Person aPerson = new Person();

Hace que el código se lea de forma más natural, creo.

Rob K
fuente
0

Absolutamente no tiene nada de malo, sujeto a las advertencias señaladas por otros (resumiendo aquí por conveniencia): no hacerlo con tipos primitivos, refactorizar la instancia original si se agrega otra instancia más tarde, no usar char-case para diferenciar nombres de clases, etc.

¿Mi regla de oro? Las declaraciones en código deben leerse como oraciones simples en inglés.

Persona persona = nueva Persona ();

Empleado empleado = person.getRole (EMPLOYEE);

Padre padre = person.getRole (PADRE);

person.getFullName ();

employee.getSalary ();

parent.getChildren ();

parent.getFullName (); // asumiendo el patrón del decorador en juego

if (person.hasRole (EMPLOYEE)) {

  ...

}

Etcétera.

Si el alcance de la variable es limitado (el método de encapsulación es de 10 a 15 líneas, por ejemplo), incluso podría usar 'p' en lugar de 'persona'. Los nombres de variables más cortos son una distracción menor cuando se trata de mantener el contexto en su cabeza. Evite los prefijos gratuitos como 'a' o (escalofrío) la notación húngara y sus derivaciones. (Eso sí, no tengo nada en contra de tales prefijos cuando se usan en el contexto apropiado: código API C ++ / COM / ATL / Win32, etc., donde ayuda a mantener las asignaciones / encasillamiento correctas).

Mis dos (!) Bits :-)

alan-p
fuente