# Errores frecuentes al programar en DKL Esta página reúne errores comunes al escribir programas en Devkron, con el mensaje que producen y la forma correcta. Todos los ejemplos usan datos ficticios. ## Un archivo incluido empieza en modo declarativo Un archivo insertado con `#include` se interpreta desde el contexto **declarativo**, aunque el programa principal esté en modo imperativo. Si el archivo contiene funciones o código imperativo, debe empezar con `#!`: ```DKL #! module "Utilerías de ejemplo:" { saludo::nombre { return "Hola, " + nombre } } ``` Sin el `#!` inicial, el contenido se toma como declaraciones y las funciones no existen: al llamarlas aparece `Función: saludo no reconocida o no registrada`. ## Los dos puntos en la descripción de `module` definen un espacio de nombres En `module "descripción:espacio.de.nombres"`, lo que sigue a `:` es el **espacio de nombres**, y se antepone al nombre de las funciones del bloque (vea [Organización y estructura del programa](Lenguaje-imperativo/Organizacion_y_estructura_del_programa.md)). Por eso un texto como `module "utilerías: lectura"` hace que la función `saludo` se llame en realidad `lectura.saludo`, y llamarla como `saludo(...)` fuera del bloque produce `Función: saludo no reconocida o no registrada`. * Si solo quiere una descripción, no use `:` en medio del texto, o póngalo al final: `module "Utilerías de ejemplo:"`. * Si quiere un espacio de nombres, llame a las funciones con el nombre completo: `util.saludo("Ana")` para `module "Utilerías:util"`. ## `list.add` espera un objeto `list.add(lista, valor)` agrega una **referencia** a la lista. Con una constante numérica (`list.add(l, 5)`) no se agrega el número: en la lista queda un objeto vacío (`{}`) sin ningún error. Para agregar valores simples de forma segura, conviértalos en objeto con `from.json`: ```DKL ref l = list.create() do list.add(l, from.json('"33"')) do list.add(l, from.json('33')) do print(to.json(l)) ``` Salida: `["33",33]`. ## `format` usa el formato de cadenas de C# El segundo argumento de `format(número, formato)` es una cadena de formato numérico de .NET (C#): | Expresión | Resultado | |---|---| | `format(1234.5, "0.00")` | `1234.50` | | `format(1234.5, "#,#.#")` | `1,234.5` | ## El incremento del `for` Si el incremento es de uno en uno, no se escribe. Si es distinto, se escribe **solo la expresión** (`a+2`), no una asignación: ```DKL for i=0; i<3 { do print("i=" + str(i)) } for a=1; a<10; a+2 { do print("a=" + str(a)) } ``` El segundo ciclo produce `a=1`, `a=3`, `a=5`, `a=7` y `a=9`. Con `a=a+2` como incremento el programa falla con `Operador inválido`. ## `#def` siempre lleva la lista de atributos por orden La sintaxis es `#def identificador (atributos por orden) "valor" (atributos predeterminados)`. La lista de atributos por orden no se puede omitir: ```DKL #include "dkli.dkh" #def emisor (Rfc, Nombre) "cfdi:Emisor" (Rfc="XAXX010101000" Nombre="" RegimenFiscal="601") #! program "ejemplo def" { ## comprobante { emisor ("EKU9003173C9", "EMPRESA DE EJEMPLO") emisor ("EKU9003173C9"; RegimenFiscal="612") } } ``` Produce: ```XML ``` Al usarlo, los valores por orden van separados por comas; después de `;` van atributos con nombre, separados por espacio, que reemplazan los valores predeterminados. `#def emisor "cfdi:Emisor" (Rfc="XAXX010101000")`, sin la lista por orden, es un error de sintaxis (`Símbolo no esperado`). ## Un nodo por línea Escriba cada nodo hijo en su propio renglón. En los registros es obligatorio: cada miembro de `new`, `using` o `member` va en su línea. Incorrecto (falla al ejecutarse con `Se esperaba un operador`, aunque `-parse` no marque error): ```DKL new r { @"a":1 @"b":2 } ``` Correcto: ```DKL new r { @"a":1 @"b":2 } ``` ## El número de línea de un error puede estar desfasado El número de línea que informa un error puede no coincidir exactamente con la línea del problema: los comentarios y los bloques entre llaves pueden desplazarlo varias líneas. Revise también las líneas anteriores a la indicada. ## "Tipos no coinciden" por una función que devolvió 0 Si una función no ejecuta ningún `return`, devuelve `0`, que es el valor de retorno predeterminado. Cuando se esperaba una cadena, el error aparece después, al usar el resultado: ```DKL nombre.cliente::id { if id > 0 { return "Cliente " + str(id) } } do print("Nombre: " + nombre.cliente(0)) ``` La última línea produce `Tipos no coinciden`. Asegúrese de que todas las rutas de la función devuelvan un valor del tipo esperado. ## Validar la sintaxis con `-parse` `dkl archivo.dkl -parse` revisa la sintaxis sin ejecutar la parte imperativa, pero **siempre termina con código 0**, aun cuando hay errores. En un script, busque el texto `Error de sintaxis` en la salida en lugar de revisar el código de salida: ```bash if ./dkl miprograma.dkl -parse 2>&1 | grep -q "Error de sintaxis"; then echo "Hay errores de sintaxis" fi ``` `-parse` no detecta errores que solo aparecen al ejecutar (como los de las secciones anteriores sobre `new` o el `for`): pruebe también ejecutando el programa.