Anterior 1 2 3 4 5 6 Siguiente

Meta comentarios

Los meta comentarios son una forma de imbuir puntos de ruptura dentro del código fuente. Esto es bastante útil, si estas escribiendo el código, y quieres añadir un punto de ruptura en alguna parte. Además, proporciona flexibilidad en la manera en que escribes el código fuente. Y eso es Bueno. Existen tres meta comentarios distintos.

Se usan de la siguiente forma:

function x() {
    ... [código script]
    //@JSD_EVAL [código script]
    ... [código script]
}

Es importante darse cuenta, que, como los puntos de ruptura, los meta comentarios no se ejecutan cuando Venkman no está siendo ejecutado. Pero a diferencia de la palabra clave debugger, esto es un comentario JavaScript real, con lo que no tendrás ningún problema con ningún navegador.

Un ejemplo

En Mozilla, carga el siguiente archivo, venkman_example_9.html. Es horrible, pero muestra los tres diferentes tipos de meta comentarios en un solo archivo. Si ejecutaras el script de forma normal, simplemente imprimiría el factorial de los números del 0 al 9. Nada demasiado impresionante.

Si examinas el código, verás que la función factorial no comprueba si el valor es un número negativo. Si le pasamos un número negativo a fac, devolverá "1", lo cual es incorrecto para los números negativos (no existe el factorial, de un número negativo.)

Inicia Venkman, y echa un vistazo al código fuente.

Código fuente
Figura 55. Viendo el código fuente de venkman_example_9.html

Antes de que los metacomentarios hagan algo, necesitas rastrearlos. En el panel de Scripts Cargados, haz click con el botón derecho sobre venkman_example_9.html.

Rastreando meta comentarios
Figura 56. Click con el botón derecho, para rastrear el archivo en busca de meta comentarios.

Enseguida te darás cuenta, de que ahora el código fuente tiene puntos de ruptura.

Venkman con puntos de ruptura establecidos
Figura 57. Usando meta comentarios para establecer puntos de ruptura en tu código automáticamente (pulsa para una versión sin escalar).

Como podemos ver, los puntos de ruptura se indican tanto en el panel Scripts Cargados (con el punto rojo), como en el panel de Puntos de ruptura, y con las "B"s en el panel del código fuente.

Lo que en realidad hacen los meta comentarios, es hacer que Venkman cree los puntos de ruptura fuertes por ti en la línea posterior a los meta comentarios (recuerda, que usar un punto de ruptura hace que Venkman pare justo antes de ejecutar la línea en la que está ¿ok?) Puedes hacer click con el botón derecho, y seleccionar las propiedades de cualquiera de estos puntos de ruptura. Aquí, en la figura 58, he seleccionado las propiedades del punto de ruptura de la línea 6.

Hoja de propiedades de puntos de ruptura
Figura 58. Una hoja de propiedades de punto de ruptura generada automaticamente.

Ahora que hemos cargado todos los meta comentarios, intenta ejecutar el script (volviendo a cargar Mozilla). Basicamente, la idea es, que una vez que los meta comentarios han sido rastreados, i tomará un valor negativo en la 7ª iteración (para el cual fac no nos dará un resultado correcto). Pero dado que ahora tenemos un punto de ruptura condicional, en fac, programado para parar la ejecución solo si el número pasado es negativo, puedes cambiar facN, una vez se le pasa a fac un número negativo.

Venkman parado
Figura 59. Venkman ha parado su ejecución, porque n<0 era cierto. Aquí, he preguntado que es n, y voy a establecer facN a "passed number was negative!" ('el número pasado era negativo!) (pulsa para una versión no escalada).

Tal como puede verse en la captura de pantalla, he parado la ejecución, y voy a devolver el mensaje "wrong number passed" (se ha pasado un número incorrecto). Normalmente, se habría devuelto 1, que es incorrecto como factorial de -4 (no hay factorial de -4 por supuesto). Esto, muestra lo siguiente en Mozilla:

factorial 0 = 1
factorial 1 = 1
factorial 2 = 2
factorial 3 = 6
factorial 4 = 24
factorial 5 = 120
factorial 6 = 720
factorial -4 = passed number was negative!
factorial 8 = 40320
factorial 9 = 362880

Por supuesto, -4 solo se pasó a fac, por el código de nuestro punto de ruptura, pero sirve para coger el concepto. Además, en lugar de simplemente devolver una cadena, podríamos haber lanzado una excepción, comprobando como reaccionaba nuestro código.

Pretty print

El uso de "Pretty Print" (literalmente Impresión Bonita), nos permite ver una función, en la forma en que JavaScript la ve. Esto es útil, cuando la función original ni tan siquiera existe en tu código, por ejemplo si se construyó usando eval, o métodos similares (setTimeout, etc). Además, también es util cuando el código fuente se ha intentado ofuscar deliberadamente (la llamada "protección de código fuente"). En Mozilla, carga el archivo venkman_example_10.html, que muestra algunos ejemplos de como utilizar "Pretty Print".

Cuando cargamos Venkman, las diferentes funciones tendrán este aspecto:

function foo() {
    var s = "function bar1(x) {debugger;return x+1;}";
    eval(s);
    return bar1(1);
}

function bar2(n) {
    while(n) n--;
    return "blah";
}

function fac(n){if(n<=0){return 1;}else{return n*fac(n-1);}}

Ten en cuenta, que la primera función (foo), contiene otra función imbuida, llamada bar1. Esto nos servirá como ejemplo de como Pretty Print nos permite ver funciones que no están "ahí". En este ejemplo, bar1 es una cadena muy simple, pero en un ejemplo real, podría ser cualquier cantidad de código, generado de la manera que quisieras.

El segundo ejemplo es mas simple, muestra un bucle while, pero no introduje las llaves opcionales. Finalmente, he escrito una función factorial recursiva. Como puedes ver, está escrita en una forma compacta, gracias al script JavaScript Crunchinator de BrainJar, el cual basicamente compacta el código (¡e indirectamente también lo hace mas dificil de leer!).

Vamos a utilizar la función Pretty Print para ver las funciones bar1, bar2 y fac. Si quieres, examina el código fuente en Venkman. Especialmente observa como la cadena s (de la que se generará la función bar1) contiene la palabra clave debugger. Cuando estes listo, vuelve a cargar la página, Venkman debería parar instantaneamente en la palabra clave debugger.

Venkman parado en 'eval'
Figura 60. Venkman ha parado la ejecución en una función que no podemos ver directamente, de forma que podría parecer "erroneo", pero no hay ningún error. Puedes utilizar la función "Pretty Print", para ver donde se ha parado realmente Venkman (pulsa para ver una versión no escalada).

Puede parecer un poco raro, que Venkman halla parado en la línea del eval (dado que esa no es la línea en la que está la palabra clave debugger.) Pero lo que está pasando es, que eval ha evaluado y declarado la función bar1, y entonces, cuando en la línea 7, se invoca a bar1, vuelve al lugar donde se definió la función (línea 6, el eval), y ahí, se para la ejecución debido a la palabra clave debugger. Para poder ver la función bar1 apropiadamente, pulsa sobre "Pretty Print".

Código fuente de bar1
Figura 61. Utilizando Pretty Print para revelar el código real de bar1, decompilado según como lo ve el engine JavaScript (pulsa para ver una versión no escalada).

También puedes añadir puntos de ruptura en este código, y si lo haces, los puntos de ruptura también se verán reflejados en el panel del código fuente "normal". Por ahora, prueba a ejecutar el código de la función paso a paso (usando "Step out"), y coloca un punto de ruptura en la línea 11, continía después ejecutando el código paso a paso hasta la función bar2. Debería aparecer una nueva pestaña, para mostrar la versión Pretty Print de bar2.

Además, mientras el depurador no está activo, puedes también ver la versión Pretty Print de las funciones. Por supuesto, cuando el script no está siendo ejecutado, Venkman no puede mostrar la versión Pretty Print de funciones que no existen aún (tal como el ejemplo con eval).

Código fuente de bar2
Figura 62. Código fuente de bar2, decompilado de la representación JavaScript interna.

Código fuente de facs
Figura 63. Código fuente de fac, decompilado de la representación JavaScript interna.

Este último ejemplo en concreto es mucho mas legible que la versión original

function fac(n){if(n<=0){return 1;}else{return n*fac(n-1);}}

Usar Pretty Print es una muy buena forma de ver código mal escrito. Desafortunadamente también elimina los comentarios. Puedes continuar ejecutando el código línea por línea, añadir puntos de ruptura, y cualquier otra cosa que pudieras hacer con código normal. Pero cuando se usa para escrutar código escrito y declarado dentro de eval, podría ser todo lo que tienes (en tiempo de ejecución). También recuerda, que todo lo comentado para eval se aplica igualmente a setTimeout.

Excluyendo código eval

Aunque tecnicamente esto debería estar en la sección depuración basica, creo que tiene mas sentido situarlo aquí (o al menos aquí se puede entender mejor, o eso espero.) Venkman te permite saltar código eval, si no quieres molestarte con él. En Mozilla, carga el siguiente archivo, venkman_example_exclude_eval.html. Verás que hay dos lugares, donde hay llamadas a eval, que contienen la palabra clave debugger. Así que queremos saltarnos estas dos. Hacer esto es tan simple como encontrar el archivo, del cual quieres excluir el código eval (también es válido para setTimeout etc.) Simplemente haz click con el botón derecho sobre el archivo como se muestra en la figura 64.

Submenú de archivo
Figura 64. Excluyendo el código de tipo eval de la depuración (pulsa para obtener una versión no escalada).

Si vuelves a cargar Mozilla (con Venkman ejecutándose), verás que no se muestra la ventana de Venkman, como pasaría normalmente, con scripts que contienen la palabra clave debugger.

Profiling

Profiling significa medir la rapidez con la que se ejecuta tu programa. Y el botón "Profile" de Venkman hace justamente eso. Tradicionalmente, la forma de medir el rendimiento de un script, consistía en incluir dentro del código un montón de objetos Date, y aplicar algo de matemáticas sobre ellos.

function foo() {
    var startDate = new Date();
    var startTime = startDate.getTime();
    
    // código
    
    var endDate = new Date();
    var endTime = endDate.getTime();
    
    // tiempo total de ejecución del script (en milisegundos):
    var totalTime = endTime - startTime;
}

Esto nos puede servir para trozos pequeños de código, o para comprobar si "esto funciona". Pero para medir el rendimiento de código complejo, es poco útil.

Para demostrar el uso de Profile, he creado una tabla DHTML, utilizando mi script de fecha. Basicamente, lo que ocurre es que he creado una fecha aleatoria, y he usado todas las opciones que permite mi script, construyendo una fila de la tabla con la salida de mi script, haciendo esto 100 veces. Y finalmente, vamos a ordenar la tabla, de forma que vaya del mas viejo, al mas nuevo (para los profesionales de JavaScript: el ejemplo está mal escrito de forma deliberada). Ejecuta el script cargando la página venkman_example_11.html (cuidado, ¡puede llevar un rato el que se ejecute!)

Ejecuta de nuevo Venkman, y simplemente pulsa sobre el botón "Profile", para comenzar el profiling.

Profiling activado
Figura 65. Se ha activado el profiling, y Venkman está tomando nota de todo lo que está ocurriendo.

Ahora mismo, Venkman está tomando nota de todo lo que está ocurriendo. Puedes volver a Mozilla, y recargar la página. Una vez que halla acabado, vuelve a Venkman, y para el profiling. Entonces en el menú "File" (Archivo), selecciona "Save Profile Data as ..." (Guardar Información de Profile como ...), e introduce el nombre del archivo donde quieras guardar la información. También es importante que introduzcas un tipo de archivo, ya que Venkman puede guardar la información en unos cuantos formatos diferentes. HTML es el mas accesible. Puedes acceder al informe del profile que cree (puede que las barras se vean un poco mal.)

En el informe generado, puedes ver todo tipo de información sobre todas las funciones, como cuantas veces se ha llamado, cuanto duraron las llamadas como media, la llamada mas larga, la mas corta, el tiempo total de las llamadas, y otras cosas. Observa, que si una función, por ejemplo foo, llama a otra función bar, el tiempo de foo incluye tanto el tiempo que tardó en ejecutarse la propia función foo, como por el tiempo que tardó bar.

Otra cosa importante que señalar, es que puedes excluir archivos, y funciones individuales para que no aparezcan en el informe. Simplemente pulsa en el archivo o la función que no quieras que se incluya, y haz click con el botón derecho sobre él.

Submenú de opciones de funciones
Figura 66. Cómo evitar que se incluya una función en el profiling.

Submenú de opciones de archivo
Figura 67. Cómo evitar que se incluya un archivo (y las funciones que incluye) en el profiling.

El profiling nos permite identificar los puntos donde se están produciendo cuellos de botella. Pero por supuesto, ninguna tabla de estadísticas te va a dar por si sola un código eficiente. Tendrás que saber como reparar estos problemas.

Una vez que hallas terminado con el profiling, no te olvides de borrar la información acumulada hasta ese momento. Si no lo haces, el próximo informe incluirá información pasada (y probablemente esto no sea lo que quieres.)

Menú de Venkman
Figura 68. Es importante borrar la información de profiling.

También puedes borrar la información de funciones o archivos individuales, siguiendo el mismo procedimiento mostrado, pero seleccionando "Clear Profile Data" (Borrar Información de Profile) en su lugar.

Una última cosa interesante sobre el profiling, es si ya has hecho el profile, y decides que no quieres la información de todo, puedes obtener la información de profile de las funciones y/o archivos que quieras.

Submenú de archivo/función de Venkman
Figura 69. Guardando la información profiled de funciones individuales, o de un archivos completo (y de las funciones que contiene) (pulsa para obtener una versión no escalada).

Fin

Uff, un poco aburrido ¿verdad? Bueno, según los logs de mi servidor ¡poca gente llega tan lejos! Dado que tú lo has hecho, me encantaría escuchar cualquier comentario que puedas tener, si has encontrado algún error, o cualquier otra cosa, que pienses que podría mejorarse.

Independientemente de lo mal escrita que esté la guía, ahora deberías ser capaz de utilizar Venkman para encontrar errores de JavaScript realmente incomprensibles. Yo aún utilizo bastante amenudo (casi siempre) alerts para depurar. Son rápidos, y la mayor parte de los errores en el código no son muy complejos. Pero algunas veces aparece un error verdaderamente complicado, o estás trabajando con bastante código (afortunadamente yo no lo suelo hacer muy amenudo), y es entonces cuando lo que has aprendido te puede resultar útil, y te permitirá depurar tu código como un profesional.

Gracias

Me gustaría dar las gracias a unas pocas personas, primero, a Robert Ginda, por contestar mis preguntas sobre los aspectos mas oscuros de algunas características de Venkman, además de a Doron Rosenberg por haber hecho que me enlacen un montón de sitios, ¡y también a la gente que me mandó sugerencias, en la primera revisión de esta guía!

Anterior 1 2 3 4 5 6 Siguiente