Es normal tener una critical section en proyectos que hacen escrituras concurrentes en variables o en una colección de variables, y si no lo haces ya tienes una pista de porqué se cae tu sistema ;).
Y es que en los anteriores post no hemos visto el trato con el código heredado o legacy code (ese gran hijo de …). Y es que es un handicap muy común en nuestro día a día.
Si este código heredado no tiene contratos, vamos a obtener algunos warnings molestos del Static Checker. Sin embargo, la API de Code Contracts nos ofrece un pequeño workarround sobre esto.
Básicamente, este tipo de warnings son debidos a la falta de información – el Checker no es capaz de encontrar la información necesaria. Sin embargo, podemos dar algunos detalles.
Vamos a mirar el siguiente código:
Código con un Warning
El checker nos avisa de una posible referencia nula. Aparentemente la variable context está siendo usada sin haber sido inicializada. ¿Quién es el responsable del warning, el Checker u otra cosa?
En este caso, el aviso lo está dando ReSharper, cuyo motor de análisis identifica una posible referencia nula. ¿Pero porqué no nos lo da el Checker?, la respuesta es por la línea:
Contract.Assume(context!=null);
Y es que con esa línea le estamos diciendo al Checker que la variable context nunca va a ser nula. El Checker confía en nosotros y añade esa información a sus procesos. Resharper no ofrece soporte completo a los contratos de .NET, de ahí el aviso. Sin embargo, ReSharper soporta su propio sistema de anotaciones que podéis usar de la misma manera. Si queréis ver más detalles pasáos por aquí.
Uso óptimo del análisis estático de código.
El análisis estático es complejo, y no suele ser una ciencia exacta. Suele ocurrir que rellenamos nuestro código con información de contratos con la mejor intención, sólo para hacer que el tiempo de compilación se dispare. Para esto hay un par de soluciones que podríamos tomar para optimizar el uso de contratos y los análisis siguientes.
La primera es crear una configuración de compilación especial y habilitar las comprobaciones sólo en esa configuración. Compilamos en esa configuración de vez en cuando para obtener información, la corregimos los posibles problemas y continuamos trabajando sin el análisis estático.
La segunda es probar a usar contratos poco a poco. Aplicamos contratos de manera extensiva en el código, pero deshabilitamos los contratos a nivel de assembly. Esto lo asemos añadiendo el siguiente atributo en las propiedades del assembly:
[assembly:ContractVerification(false)]
Lo siguiente, es re-habilitar el checkeo de contratos sólo cuando estemos centrados en clases, métodos o assemblies.
Aviso
El análisis estático de código es una técnica que intenta evaluar el correcto funcionamiento de vuestro código sin ejecutarlo. Hay algunas herramientas que hacen esto. La primera es el compilador, otra es el Static Checker – un ejecutable que se integra en el proceso de compilación. En .NET, una herramienta especial aprende desde los contratos que tengáis, evalúa la información y nos muestra posibles errores y violaciones de contratos.
En el momento en el que la complejidad aumenta continuamente y el equipo de desarrollo se va quedando sin tiempo, integrar este tipo de herramientas salva algún tiempo de compilación, pero más importante, nos protege de errores feos en nuestro software.
Pasa muchas veces, que cuando le enseñas a alguien tu código te quedas con cara de tonto. A mi me pasa mucho, y aún sabiendo que tengo herramientas disponibles para evitarlo en gran medida. Estoy hablando de las herramientas de análisis estático de código.
Cada vez son más las herramientas disponibles. Incluso la última versión del compilador de C# busca violaciones del principio de Liskov, sin embargo no lo califica como un error sino como sólo un warning.
Visual Studio 2010 viene con una nueva característica de análisis de código que podemos usar para realizar un análisis más profundo y evitar sonrojarnos cuando enseñamos nuestro código:
Opciones de Visual Studio 2010
Incluso se pueden establecer y personalizar las reglas que queremos cumplir:
Warnings de VS 2010
Estas herramientas nos ofrecen avisos sólo cuando se incumplen estas reglas. Incumplir una regla no significa que haya un bug, sólo indica que hay un posible bug y es mejor hecharle un vistazo sin esperar a que aparezca Murphy por ahí diciéndonos: “te lo dije, si algo puede fallar, fallará”.
¿Trabajas con TDD? ¿Haces test unitarios con MSTests? ¿Tienes una máquina con varias cpus?.
Sip, parece un mundo ideal sobre todo por lo de hacer TDD, ;). Sin embargo como los TDDadores son como las meigas … (existir no existen, pero haberlas haylas). Seguramente tendrán máquinas multicore y posiblemente haran test con Visual Studio 2010 y MSTests.
Hemos abierto una nueva sección en este nuestro blog llamada “Lecturas Recomendadas” destinada a recomendar libros y material sobre este mundo que tanto nos apasiona.
Lo iremos actualizando de vez en cuando así que estad atentos a los cambios, y si os apetece aportar vuestros 2 cents, no lo dudéis y comentadlo.