language agnostic - ¿Dónde envolver una línea de código, especialmente largas listas de argumentos?
language-agnostic wrapping (14)
Para mí, depende de cuánto tiempo es la lista de argumentos. No me gusta mucho el diseño de fin de línea y casi requiere una compatibilidad de editor (por ejemplo, emacs) para hacerlo bien.
Si la llamada al método es lo suficientemente corta como para ponerla en una línea, haré esto:
int SomeReturnValue =
SomeMethodWithLotsOfArguments(Argument1, Argument2, ...);
Si el método y la variable encajan en una línea y los argumentos en otra, lo he hecho:
int SomeReturnValue = SomeMethodWithLotsOfArguments
(Argument1, Argument2, ... );
Eso hace que mi corazón LISPy sonría, pero vuelvo loco a mis colegas, así que he cedido:
int SomeReturnValue = SomeMethodWithLotsOfArguments(
Argument1, Argument2, ... );
Supongo que estoy tratando de decir que no he encontrado una solución con la que estoy realmente feliz, aunque esto tiene cierto atractivo para los casos realmente demasiado largos debido a su similitud con la forma en que presentamos los cráneos:
int SomeReturnValue = SomeMethodWithLotsOfArguments(
Argument1,
Argument2,
);
¿Cuál es tu forma preferida de envolver líneas de código, especialmente cuando se trata de largas listas de argumentos?
Ha habido varias preguntas relacionadas con las líneas de envoltura (como cuando escribo código, ¿envuelve el texto o no? Y el formato de ancho de línea estándar ), pero no he podido encontrar uno que cubra dónde ajustar una línea de código.
Digamos que tenemos una línea de código que sigue y sigue como este ejemplo:
int SomeReturnValue = SomeMethodWithLotsOfArguments(Argument1, Argument2, Argument3, Argument4);
¿Cómo debería ser eso envuelto?
Aquí hay algunas maneras en que puedo pensar, y algunas de sus desventajas:
int SomeReturnValue = SomeMethodWithLotsOfArguments(Argument1, Argument2,
Argument3, Argument4);
Personalmente, no prefiero esa opción porque el formato parece separar visualmente la lista de argumentos del método que estoy tratando de invocar, especialmente porque hay una tarea igual al signo ("=") justo encima de los argumentos orphanged en la nueva línea.
Por lo tanto, durante un tiempo fui con el siguiente enfoque:
int SomeReturnValue = SomeMethodWithLotsOfArguments(Argument1,
Argument2,
Argument3,
Argument4);
Aquí, los argumentos están agrupados, todos en el lado del primer argumento del método. Sin embargo, una pega es que la lista de argumentos no siempre se alineará en la segunda línea en adelante debido a la cantidad de espacios que sangra la pestaña. (Y escribir espacios adicionales para formatear sería demasiado lento).
Una respuesta en una de las preguntas anteriores sugería el siguiente formato:
int SomeReturnValue = SomeMethodWithLotsOfArguments(
Argument1,
Argument2,
Argument3,
Argument4
);
De hecho, me gusta este formato, debido a su atractivo visual, pero también distingue visualmente los argumentos del método al que pertenece la lista. Además, prefiero tener una llamada de método único que no ocupe demasiadas líneas.
Entonces, mi pregunta es, sin entrar en el tema de evitar que un código de línea sea demasiado largo en primer lugar , ¿cómo recomendaría que se envuelvan líneas de código? Específicamente, ¿ dónde es un buen lugar para romper una línea de código, cuando se trata de largas listas de argumentos?
En funciones con lista de parámetros larga, envuelvo después de cada uno o dos parámetros para la legibilidad (siempre manteniendo el mismo número de parámetros en cada línea):
int SomeReturnValue = SomeMethodWithLotsOfArguments(Argument1,
Argument2,
Argument3,
Argument4);
O
int SomeReturnValue = SomeMethodWithLotsOfArguments(Argument1, Argument2,
Argument3, Argument4);
dependiendo de la longitud de la lista / parámetro.
Intento mantener las líneas cortas. En este caso, rompería antes de la asignación y después de cada parámetro. También puse la coma al principio de la línea para que sea más fácil agregar nuevos argumentos:
int SomeReturnValue
= SomeMethodWithLotsOfArguments(
Argument1
, Argument2
, Argument3
, Argument4
);
Usar este tipo de diseño es mucho trabajo en Visual Studio, pero Emacs lo hace de forma automática.
La mayoría ha hecho buenas sugerencias sobre la sangría y esto es excelente para las funciones de la API que no controlas. Si controlas la API, te sugiero que una vez que tengas más de 3 argumentos, debes crear alguna forma de estructura y pasar la estructura a la rutina. Una vez que obtenga más de 3 argumentos, la posibilidad de pasarlos en el orden incorrecto va en aumento. También le da más visibilidad al tipo y significado de los parámetros.
someStruct.x = somevalue;
somestruct.y = someothervalue;
int someResturnValue - SomeMethod(somestruct);
La opción 3 sugerida
int SomeReturnValue = SomeMethodWithLotsOfArguments(
Argument1,
Argument2,
Argument3,
Argument4
);
es una mejor manera, ya que da una buena sensación. Si la duración de los argumentos es más o menos la misma, entonces podemos unirlos para que se alineen como una tabla, por ejemplo
int SomeReturnValue = SomeMethodWithLotsOfArguments(
Argument1, Argument2, Argument3, Argument4,
Argument005, Argument006, Argument7, Argument8
);
No hay una respuesta definitiva para mí sobre esto. Lo hago caso por caso. Si el nombre de la función es largo, definitivamente no sangro los otros argumentos a la misma columna que los argumentos anteriores. Si el nombre de la función es corto, suelo sangrar los siguientes argumentos en la misma columna, recopilando todos los argumentos que puedo en una línea (no un argumento = una línea). Pero si hay alguna simetría agradable, como en
int a = foo(a + b,
c + d);
probablemente rompería esa regla y tendría el mismo número de argumentos en cada línea.
Personalmente, no me gusta la segunda opción, demasiado cercana al arte Ascii, con sus inconvenientes en el código: cambie el nombre de la función, debe volver a sangrar todos los argumentos. Y de alguna manera hincha el archivo. Además, no funciona bien si utiliza pestañas duras en el código.
La mayoría de las veces, utilizo la primera opción, pero adopté la regla Eclipse de dos sangrías para líneas de continuación, ya que se destaca mejor de la sangría normal (particularmente si divide las instrucciones condicionales).
En algún momento utilizo la segunda opción, ej. si el paréntesis de apertura ya está cerca del límite de mi longitud de línea ...
Ventaja: puede agregar un comentario de línea después de cada parámetro.
O me gusta Dheer, agrupando argumentos hasta que llenen el ancho de la línea.
El hecho de que los argumentos estén separados del nombre de la función nunca me molestó, todavía están cerca y bastante agrupados. En el peor de los casos, puedo poner líneas en blanco alrededor de la llamada a la función.
Siempre rompo antes de la tarea si eso deja intacto el lado derecho. Esto es útil en idiomas como Java, donde tiene que declarar explícitamente el tipo de valor asignado.
SomeVeryVerboseTypeName SomeReturnValue
= SomeMethodWithLotsOfArguments(Argument1, Argument2, ...);
También uso la ''opción de sangría consistente'' citada por Edward Kmett. Si hay muchos argumentos, tiendo a agruparlos en línea por afinidad siempre que sea posible.
Pero para este ejemplo en particular, probablemente lo deje en una línea, no es tan largo.
No soporto el formato de "envoltura colgante" ya que puede proporcionar una confusión visual que está en conflicto con el sangrado (mucho más importante). Las envolturas colgantes se consideran el estilo ''predeterminado'' para muchos idiomas en este momento, pero no sé cómo se puso de esa manera. Es IMHO horrible.
Yo prefiero de esta manera:
int SomeReturnValue = SomeMethodWithLotsOfArguments(Argument1, Argument2,
Argument3, Argument4);
Donde la línea termina más cerca de su ancho de línea máximo actual (lo que sea que sea) y la siguiente línea se sangra su nivel de sangría habitual (lo que sea que sea) en relación con el signo de igual.
No estoy seguro de por qué, pero creo que es la opción más fácil de leer en la mayoría de las situaciones. Sin embargo, elegí no ser pedante acerca de estas cosas y siempre prefiero lo que sea más legible para una determinada sección de código, incluso si eso puede romper algunas reglas de sangría o formato (dentro de ciertos límites, por supuesto).
Un ejemplo de esto sería si la función requiriera muchos argumentos o los argumentos en sí mismos complejos, entonces podría elegir algo como esto en su lugar:
int SomeReturnValue = SomeMethodWithLotsOfArguments(
Argument1 + Expression1 + Expression2,
Argument2 - Expression3 * Expression4,
Argument3,
Argument4 * Expression5 + Expression6 - Expression7);
Por supuesto, si las expresiones del argumento son muy largas o complejas, sería mejor hacer los cálculos antes de la llamada a la función y usar valores temporales para almacenar los resultados.
advertencia: yo uso IDEs. Si no eres un usuario de IDE, simplemente sáltate esto.
Al trabajar con otros:
Tiendo a seguir cualquier convención adoptada actualmente por el equipo. Mejor aún si el equipo usa un IDE con soporte de formato de código. Siempre pegue con las convenciones de formato team / IDE. No puedo decirte cuántas veces he sido quemado por "version-contro-diff-hell-due-to-reformats"
Cuando trabajas solo:
Enciendo el método, la longitud de línea no es un problema para mí. Tengo un buen monitor de pantalla ancha y las barras de desplazamiento horizontales se inventaron por una razón. Además de eso, navegar por el código fuente es mucho más que un desplazamiento visual ahora que muchos IDE tienen utilidades como árboles de llamadas, encontrar referencias y herramientas de refactorización.
int SomeReturnValue = SomeMethodWithLotsOfArguments
( Argument1,
Argument2,
Argument3,
Argument4
);
primero
Si los args son lo suficientemente cortos y tienen una longitud (casi) similar, creo que por debajo son visualmente lo suficientemente buenos
int variable_with_really_long_name = functionWhichDoMore(Argument1, ArgumentA2,
ArgumentA3, Argument4,
ArgumentA5, Argument6);
Segundo
Cuando empeora, una columna de argumento realmente ayuda
int variable_with_really_long_name = somefunctionWhichDoMore(Argument_Expand1,
Argument2,
Argument_Expand3,
Argument_Expand4,
Argument_Expand5,
Argument6);
Tercero
Pero, ahora, ¿cómo es si empeora? ¿Ahora que? Prueba este
int variable_with_really_long_name = someFunctionWhichDoMore
(
Argument_Expand_More1,
Argument_Expand_More2,
Argument_Expand3, Argument4,
Argument_Expand_More5, Argument6
);
Por cierto, si quieres un aspecto consistente, utiliza el tercero en todas las condiciones anteriores.
Justifica: se pone bien y sabemos que es una llamada a función con muchos (6) argumentos. ¡Y me gusta que mi código se vea limpio y !(so_ugly)
.
Los críticos son bienvenidos. Por favor coméntalo.
Prefiero lo siguiente
int variable_with_really_long_name = functionWhichDoMore(
Argument1, ArgumentA2, ArgumentA3, Argument4,
ArgumentA5, Argument6);
int i = foo(Argument1, ArgumentA2, ArgumentA3, Argument4,
ArgumentA5, Argument6);
Ambos son consistentes entre sí, cuando alcanzo los 80 caracteres, voy a la siguiente línea y coloco 2 sangrías de 4 espacios cada una. Mi argumentación para esto es la siguiente:
Uso 2 sangrías de 4 espacios cada una, para visualizar claramente el hecho de que se trata de una línea envuelta y no de un bloque de código sangrado.
Esta forma de sangría mantiene el código muy sangrado porque siempre sigue el mismo patrón de sangría, 2 sangrías para el ajuste de línea, 1 sangría para bloques de código.
Colocar cada argumento en una línea separada puede resultar en métodos muy grandes, por lo tanto, prefiero argumentos secuencialmente en una o más líneas.
Esta forma de ajuste de línea se puede configurar en un IDE como Eclipse, proporcionando la capacidad de formatear automáticamente.
Sin embargo, hay una nota importante, puede haber casos excepcionales en los que ocurre lo siguiente:
int variable_with_really_long_name = functionWhichDoMore(arg1,
arg2)
Trataré de evitar esto, si sucede, haré lo siguiente
int variable_with_really_long_name = functionWhichDoMore(arg1, arg2)
Sí, pasaré mi 120 char máx. convención de longitud de línea de código, mi convención es realmente flexible en esto, máx. 120 a 140 caracteres, normalmente envuelvo después de 120, sin embargo, en este caso voy a ir al máximo. 140 caracteres La desventaja de esto es, por supuesto, que no se puede configurar para auto-formatear en un IDE como eclipse.
PD. Sé que algunas personas piensan que 120 caracteres es demasiado para la longitud de la línea de código, pero esa es otra discusión. Las convenciones anteriores también pueden aplicarse para 80/100 caracteres.