martes, marzo 05, 2013

Autoformateo de código en Eclipse: Curly Brackets y Max Line Length


La convención de formato para código Java parece indicar que las llaves (curly brackets o braces) que abren clases, métodos y sentencias de control van a la derecha de la definición/sentencia, en la misma línea:

class MiClase {
    ...
}

if( condicion ) {
    ...
}

No obstante, yo, desde hace 15 años (en C) estoy acostumbrado a poner la llave en la siguiente línea, indentada al mismo nivel que la línea de cierre:

class MiClase 
{
    ...
}

if( condicion ) 
{
    ...
}

Sinceramente, a mí me parece más legible e intuitivo para encontrar los diferentes niveles de indentado de código, por lo que no termino de acostumbrarme a poner la llave de apertura a la derecha en la misma línea.

Entiendo que esto se realiza para poder diferenciar estas llaves de las llaves que se pueden usar para definir ámbitos locales para variables:

{
    {
        int i;
        for i in (blah; ... )
        {
        }

    } // i desaparece con este cierre de ámbito
}

Pero, insisto, yo me he acostumbrado a ponerlas en una nueva línea y mucho más desde que programo en Python, donde tengo la costumbre de indentar perfectamente y con 4 espacios, y que ahora me hace casi imposible escribir código Java de la forma "habitual" para los demás desarrolladores.

El problema que tengo es que cuando pulso CTRL+ALT+F (formatting) en Eclipse, me formatea todo el código con la convención "habitual".

Por suerte, he visto que se puede cambiar, tanto eso como el tamaño máximo de línea:

[stackoverflow]/how-do-i-change-the-code-convention-in-eclipse

+


Window -> Preferences -> Java -> Code style -> Formatter view

Create a new profile based on the eclipse built in, then go to braces tab and change "same line" to next line everywhere. Then set the new profile to default.


[stackoverflow]/eclipse-set-maximum-line-length-for-auto-formatting


In preferences Java -> Code Style -> Formatter, edit your profile. Under the Line Wrapping tab is the option for line width (Maximum line width:).

Comments have their own line length setting at the bottom of the setting page Java -> Code style -> Formatter -> Edit... -> Comments



EL DEBATE: CONVENCIÓN VS ESTILO PERSONAL


Tengo sentimientos encontrados al respecto de este cambio.

Por un lado, pienso que es un error ir contra las convenciones generales, porque es importante mantener un estilo similar en todo el código. Y si trabajas en equipo, esto es un problema. Tal vez lo ideal sería acostumbrarse a la convención habitual.

Por otro, para mí es MUCHO más legible el código en este formato. Veo mucho más claro el ámbito de cada clase, método, función o bloque de código en una sentencia de control. Es una reminiscencia de Python, entiendo, pero me ocurre. Y claro, al no ser un programador profesional (como amablemente me recuerda constantemente Fede), el código que voy a crear y mantener probablemente será siempre sólo y exclusivamente mío... Ahora bien, esto es lo que me dice el corazón. La cabeza me dice que cuanto antes me acostumbre a la convención original más fácil me resultaré después leer el código de otros, utilizar código de otros o que otros trabajen conmigo, incluso en otros lenguajes.

La postura oficial de convención para código de Sun y de Oracle es clara al respecto:

[oracle.com]/Code Conventions for the Java TM Programming Language


6.4 Class and Interface Declarations

When coding Java classes and interfaces, the following formatting rules should be followed:
  • No space between a method name and the parenthesis "(" starting its parameter list
  • Open brace "{" appears at the end of the same line as the declaration statement
  • Closing brace "}" starts a line by itself indented to match its corresponding opening statement, except when it is a null statement the "}" should appear immediately after the "{"
class Sample extends Object {
    int ivar1;
    int ivar2;

    Sample(int i, int j) {
        ivar1 = i;
        ivar2 = j;
    }

    int emptyMethod() {}

    ...
}
  • Methods are separated by a blank line


Es decir, la llave en la misma línea :-(.

Me gusta un poco más lo que se propone aquí para PHP:

[github.com]/PSR-2 Coding Style Guide


1.1. Example

This example encompasses some of the rules below as a quick overview:
php
namespace Vendor\Package;

use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class Foo extends Bar implements FooInterface
{
    public function sampleFunction($a, $b = null)
    {
        if ($a === $b) {
            bar();
        } elseif ($a > $b) {
            $foo->bar($arg1);
        } else {
            BazClass::bar($arg2, $arg3);
        }
    }

    final public static function bar()
    {
        // method body
    }
}


Un mix: clases, métodos y funciones con las llaves en la siguiente línea, ifs, whiles, etc con las llaves en la misma. Eso sí, el elseif y el else junto a las llaves de cierre me provocan dolor de ojos...

¿Opiniones?


EDIT:

Veo que lo mío con las llaves tiene nombre: "Allman Style", y no soy el único que defiende este formato de código (el creador de C++ también lo utiliza). Es una variante del Estilo K&R:

http://en.wikipedia.org/wiki/Indent_style



K&R style

The K&R style, so named because it was used in Kernighan and Ritchie's book The C Programming Language, is commonly used in C. It is also used for C++C#, and others.[citation needed]
When adhering to K&R, each function has its opening brace at the next line on the same indentation level as its header, the statements within the braces are indented, and the closing brace at the end is on the same indentation level as the header of the function at a line of its own. The blocks inside a function, however, have their opening braces at the same line as their respective control statements; closing braces remain in a line of their own, unless followed by an else or while keyword.[citation needed]
In this style a control statement with only a single statement in its scope may omit the braces. The C Programming Language refers to this as fertile soil for bugs (programming logical errors) and discourages it.
int main(int argc, char *argv[])
{
    ...
    while (x == y) {
        something();
        somethingelse();
 
        if (some_error) {
            /* the curly braces around this code block could be omitted */
            do_correct();
        } else
            continue_as_usual();
    }
 
    finalthing();
    ...
}




Allman style

The Allman style is named after Eric Allman. It has been incorrectly referred to as "ANSI style"[7] supposedly for its use in the documents describing the ANSI C standard (later adopted as the ISO C international standard), though in fact those documents use K&R style.[8] It is also sometimes known as "BSD style" since Allman wrote many of the utilities for BSD Unix(although this should not be confused with the different "BSD KNF style"; see below). This style has also been adopted by Bjarne Stroustrup in his books, The C++ Programming Language.
This style puts the brace associated with a control statement on the next line, indented to the same level as the control statement. Statements within the braces are indented to the next level.
while (x == y)
{
    something();
    somethingelse();
}
 
finalthing();
This style is similar to the standard indentation used by the Pascal programming language and Transact-SQL, where the braces are equivalent to the begin and end keywords.
Advantages of this style are that the indented code is clearly set apart from the containing statement by lines that are almost completely whitespace, improving readability, and the closing brace lines up in the same column as the opening brace, making it easy to find matching braces. Additionally, the blocking style delineates the actual block of code from the associated control statement itself. Commenting out the control statement, removing the control statement entirely, refactoring, or removing of the block of code is less likely to introduce syntax errors because of dangling or missing brackets.
For example, the following is still syntactically correct:
//while (x == y)
{
    something();
    somethingelse();
}
As is this:
//for (int i=0; i < x; i++)
//while (x == y)
if (x == y)
{
    something();
    somethingelse();
}
Even like this, with conditional compilation:
char c;
#ifdef HAS_GETCH
while ((c = getch()) != EOF)
#else
while ((c = getchar()) != EOF)
#endif
{
    do_something(c);
}
Each of the enclosing braces occupies an entire line by itself without adding any actual code. Whether this makes the code easier or harder to read is debated.


Por lo que veo en Stackexchange o StackOverflow, no soy el único que ha iniciado debates similares:

[programmers.stackexchange.com]/should-curly-braces-appear-on-their-own-line


En la siguiente encuesta gana por goleada el Allman Style (sólo seguido, con el 50% de los votos que el Allman, por el K&R):

[terminally-incoherent.com]/the-only-correct-indent-style

Sin embargo, sí que puede tener consecuencias negativas en Javascript, con "return":

[stackoverflow]/dangerous-implications-of-allman-style-in-javascript

El debate sigue abierto ... en otros foros donde lo he lanzado, la mayoría de la gente opina que me ciña a la convención general del lenguaje, pero cuanto más código miro con la convención general de Java, más claro y simple me parece el estillo Allman...

No hay comentarios: