|
| 1 | +--- |
| 2 | + |
| 3 | +name: Depuración |
| 4 | +theory: | |
| 5 | +
|
| 6 | + Incluso a los desarrolladores más experimentados rara vez les funciona el código a la perfección al primer intento. Cuanto más experimentado es el desarrollador, con más confianza lo **depura**, es decir, analiza los errores y los corrige. |
| 7 | +
|
| 8 | + La habilidad de depuración no aparece por sí sola. Hay que desarrollarla, y cuanto antes mejor. A lo largo del aprendizaje realizarás tareas y practicarás, y con el tiempo el análisis de errores se convertirá en un hábito. |
| 9 | +
|
| 10 | + ## Cómo encontrar un error en el código |
| 11 | +
|
| 12 | + Depurar a base de prueba y error lleva mucho tiempo. Es mucho más productivo entender primero qué salió mal y luego corregir la causa. Todo trabajo con errores comienza con la comprensión. |
| 13 | +
|
| 14 | + Lo primero es estudiar la **pila de llamadas** (stack trace). Contiene una lista de todas las llamadas a funciones desde el punto del error hasta el inicio del programa. Muestra qué funciones se ejecutaron y dónde surgió el problema. Cada entrada indica un archivo, una línea y la función que se estaba ejecutando. |
| 15 | +
|
| 16 | + Imagina que escribiste código en un archivo `users.js` y llamaste a la función `main()`, que internamente llama a una `create()` inexistente: |
| 17 | +
|
| 18 | + ```javascript |
| 19 | + const main = () => { |
| 20 | + create(); |
| 21 | + }; |
| 22 | +
|
| 23 | + main(); |
| 24 | + ``` |
| 25 | +
|
| 26 | + Al ejecutarlo verás una salida así: |
| 27 | +
|
| 28 | + ```bash |
| 29 | + ReferenceError: create is not defined |
| 30 | + at main (users.js:2:3) |
| 31 | + at users.js:5:1 |
| 32 | + ``` |
| 33 | +
|
| 34 | + La primera línea es el **mensaje de error**. Aquí `ReferenceError: create is not defined` dice que el nombre `create` no está definido. Este error suele significar un error tipográfico en el nombre. |
| 35 | +
|
| 36 | + Debajo está la propia pila de llamadas. Se ve que el programa llegó a `main()` (línea 5), dentro de ella llamó a `create()` (línea 2) y aquí se topó con el error. Cada entrada `at ...` indica un archivo y una línea. |
| 37 | +
|
| 38 | + ## Tipos de errores |
| 39 | +
|
| 40 | + Los errores más comprensibles son los **errores de sintaxis**. Surgen cuando el código está mal formateado, por ejemplo, por un paréntesis sin cerrar o comillas que no coinciden. La salida siempre contiene `SyntaxError`: |
| 41 | +
|
| 42 | + ```bash |
| 43 | + console.log("Hello" + 'world); |
| 44 | + ^^^^^^^^ |
| 45 | + SyntaxError: Invalid or unexpected token |
| 46 | + ``` |
| 47 | +
|
| 48 | + Los más difíciles de corregir son los **errores de programación**. Entre ellos están llamar a una función inexistente, usar una variable no declarada o pasar argumentos de tipo incorrecto. Suelen aparecer en un lugar distinto al de la causa real, lo que dificulta el diagnóstico. |
| 49 | +
|
| 50 | + Los más difíciles de combatir son los **errores lógicos**. El programa funciona sin excepciones, pero produce un resultado incorrecto con ciertos datos de entrada. No hay ningún mensaje de error, solo una salida inesperada. Por ejemplo, una función que debería calcular la suma pero calcula la diferencia: |
| 51 | +
|
| 52 | + ```javascript |
| 53 | + // La función debería calcular la suma de los números, pero calcula la diferencia: |
| 54 | + const sum = (a, b) => a - b; |
| 55 | +
|
| 56 | + // Con esta llamada el error no es evidente, porque |
| 57 | + // tanto la suma como la resta dan el mismo resultado |
| 58 | + sum(4, 0); // 4 |
| 59 | + ``` |
| 60 | +
|
| 61 | + ## Métodos de depuración |
| 62 | +
|
| 63 | + En la base de cualquier método de depuración está la observación de las variables durante la ejecución. Veamos una función concreta. |
| 64 | +
|
| 65 | + A continuación, una función que calcula la suma de los números desde `start` hasta `finish`. Con `start=3` y `finish=5` debería calcular `3 + 4 + 5`. |
| 66 | +
|
| 67 | + ```javascript |
| 68 | + const sumOfSeries = (start, finish) => { |
| 69 | + let result = 0; |
| 70 | + let n = start; |
| 71 | + while (n < finish) { |
| 72 | + result = result + n; |
| 73 | + n = n + 1; |
| 74 | + } |
| 75 | +
|
| 76 | + return result; |
| 77 | + }; |
| 78 | + ``` |
| 79 | +
|
| 80 | + Las variables clave de esta función son `n` y `result`. Para encontrar el error, hay que ver qué valores toman en cada iteración. |
| 81 | +
|
| 82 | + Para ello existen los **depuradores visuales**. Se integran en los editores de código populares y permiten ejecutar el programa paso a paso, observando las variables en tiempo real. Puedes encontrar uno buscando «JavaScript debuggers» en Google. |
| 83 | +
|
| 84 | + En el entorno de Hexlet, en lugar de un depurador se usa la **impresión de depuración**. El principio es el mismo, solo que los valores de las variables se imprimen con el habitual `console.log`. Lo que se imprime aparece en la pestaña `OUTPUT`. |
| 85 | +
|
| 86 | + ```javascript |
| 87 | + const sumOfSeries = (start, finish) => { |
| 88 | + let result = 0; |
| 89 | + let n = start; |
| 90 | + while (n < finish) { |
| 91 | + console.log('new iteration !!!!'); |
| 92 | + console.log(n); |
| 93 | + result = result + n; |
| 94 | + n = n + 1; |
| 95 | + console.log(result); |
| 96 | + } |
| 97 | +
|
| 98 | + return result; |
| 99 | + }; |
| 100 | +
|
| 101 | + sumOfSeries(3, 5); |
| 102 | +
|
| 103 | + // new iteration !!!! |
| 104 | + // 3 |
| 105 | + // 3 |
| 106 | + // new iteration !!!! |
| 107 | + // 4 |
| 108 | + // 7 |
| 109 | + ``` |
| 110 | +
|
| 111 | + La salida muestra que hay una iteración menos de las necesarias. El cinco (`finish`) no entró en la suma. La condición usa `n < finish` en lugar de `n <= finish`. Hay que reemplazar el signo `<` por `<=`. |
| 112 | +
|
| 113 | + Los principiantes a menudo se molestan por los errores y se consideran descuidados. Todos cometen errores, tanto los junior como los senior. La diferencia está en con cuánta seguridad los encuentras. |
| 114 | +
|
| 115 | + Los principiantes piensan que un buen desarrollador mira el código y entiende de inmediato qué está mal. Esto rara vez funciona en la práctica. Un fragmento de código sin contexto dice muy poco. **Si quieres pedir consejo a un desarrollador experimentado, lo primero es mostrarle el mensaje de error.** |
| 116 | +
|
| 117 | +instructions: | |
| 118 | +
|
| 119 | + Implementa la función `compress(str)` que comprime una cadena usando RLE (Run-Length Encoding). |
| 120 | +
|
| 121 | + Algoritmo: si un carácter se repite consecutivamente, se reemplaza por el carácter y la cantidad. Los caracteres individuales se escriben sin número. |
| 122 | +
|
| 123 | + ```javascript |
| 124 | + compress('aaabcccc'); // => 'a3bc4' |
| 125 | + compress('abcd'); // => 'abcd' |
| 126 | + compress('aabbaa'); // => 'a2b2a2' |
| 127 | + compress(''); // => '' |
| 128 | + ``` |
| 129 | +
|
| 130 | + Este algoritmo se utiliza en formatos reales de compresión de datos, por ejemplo, en antiguos protocolos de fax y archivos BMP. |
| 131 | +
|
| 132 | + ### Algoritmo |
| 133 | +
|
| 134 | + 1. Recorrer la cadena contando la cantidad de caracteres idénticos consecutivos. |
| 135 | + 2. Cuando el carácter cambie, escribir el carácter anterior y el contador (si es mayor que 1). |
| 136 | + 3. No olvidar procesar el último grupo después de que termine el bucle. |
| 137 | +
|
| 138 | +tips: [] |
| 139 | + |
| 140 | +definitions: [] |
0 commit comments