DocumentaciónTablas y Registros

Tablas y Registros

Las tablas en BLOX son una de las estructuras más potentes y flexibles del lenguaje.
Permiten representar colecciones de registros, donde cada registro agrupa pares campo = valor.

Una tabla puede usarse para:

  • almacenar datos tipo lista
  • representar filas de una planilla
  • trabajar con registros heterogéneos
  • importar y exportar datos
  • buscar, filtrar, mezclar y transformar información

¿Qué es una tabla en BLOX?

Una tabla es un conjunto ordenado de registros.

Cada registro contiene campos con nombre, por ejemplo:

  • nombre
  • edad
  • ciudad

y cada campo puede guardar distintos tipos de dato:

  • NUMERICO
  • STRING
  • LOGICO
  • VECTOR
  • MATRIZ
  • TABLA
ejemplo.blox
TABLA personas

personas = { nombre = "Ana", edad = 28, ciudad = "Asuncion" }
personas = { nombre = "Luis", edad = 35, ciudad = "Encarnacion" }

En este ejemplo:

  • personas es una tabla
  • personas[1] es el primer registro
  • personas[2] es el segundo registro

Tip: Las tablas se expanden automáticamente a medida que agregas registros. No necesitas definir previamente la cantidad de filas ni los nombres de los campos.

¿Qué es un registro?

Un registro es una sola fila lógica dentro de una tabla.

ejemplo.blox
TABLA personas

personas = {
    nombre = "Carlos",
    edad = 30,
    ciudad = "Asuncion"
}

Aquí, personas[1] es un registro con tres campos:

  • nombre
  • edad
  • ciudad

Puedes imprimirlo directamente:

ejemplo.blox
IMPRIMIR(personas[1])

Crear tablas

Crear una tabla vacía

ejemplo.blox
TABLA personas

Agregar registros

ejemplo.blox
TABLA personas

personas = { nombre = "Ana", edad = 28 }
personas = { nombre = "Luis", edad = 35 }
personas = { nombre = "Marta", edad = 22 }

Cada asignación de este tipo agrega un nuevo registro al final de la tabla.

Acceso a registros y campos

Acceso por índice

ejemplo.blox
registro = personas[1]

Acceso por nombre de campo

ejemplo.blox
nombre = personas[1].nombre
edad   = personas[1].edad

Acceso con corchetes

ejemplo.blox
nombre = personas[1]["nombre"]
edad   = personas[1]["edad"]

Acceso dinámico a campos

Esto es útil cuando el nombre del campo está en una variable:

ejemplo.blox
STRING campo, valor

campo = "nombre"
valor = personas[1][campo]

Modificar valores

Puedes modificar un campo existente de esta forma:

ejemplo.blox
personas[2].ciudad = "Ciudad del Este"

o con clave dinámica:

ejemplo.blox
STRING campo

campo = "ciudad"
personas[2][campo] = "Ciudad del Este"

Regla importante: creación automática de campos

En BLOX, una asignación como:

ejemplo.blox
tabla[i][campo] = valor
tabla[i].campo = valor

tiene esta semántica:

  • si el campo ya existe, se modifica
  • si el campo no existe, se crea automáticamente y luego se asigna el valor

Ejemplo:

ejemplo.blox
TABLA personas

personas = { nombre = "Roberto", ciudad = "Concepcion" }

personas[1].email = "rob@mail.com"

Resultado:

ejemplo.blox
{
    nombre = "Roberto",
    ciudad = "Concepcion",
    email = "rob@mail.com"
}

Nota importante: Este comportamiento es parte aceptada del lenguaje. No se considera un error.

Modo estricto con ES_CAMPO()

Si no quieres que un campo se cree automáticamente, puedes proteger la asignación con ES_CAMPO().

ejemplo.blox
SI (ES_CAMPO(personas[1], "edad")) ENTONCES
    personas[1].edad = 23
SINO
    ERROR("Campo inexistente.")
FIN_SI

Esto es útil cuando quieres distinguir entre:

  • modificar un campo existente
  • crear accidentalmente un campo nuevo por error tipográfico

Tablas heterogéneas

En BLOX, no todos los registros tienen que tener los mismos campos.

ejemplo.blox
TABLA personas

personas = { nombre = "Carlos", edad = 30, ciudad = "Asuncion" }
personas = { nombre = "Juan", edad = 21, ciudad = "Encarnacion" }
personas = { nombre = "Roberto", ciudad = "Concepcion", email = "rob@mail.com" }

Aquí:

  • los registros 1 y 2 tienen edad
  • el registro 3 no tiene edad
  • el registro 3 tiene email
  • los demás no tienen email

Por eso, en tablas heterogéneas conviene usar:

  • ES_CAMPO(reg, campo)
  • CLAVES(reg)
  • CLAVES_INFO(reg)
  • TIPO_DATO(tabla, campo)

Subtablas

Un campo también puede contener otra tabla.

ejemplo.blox
TABLA personas

personas = {
    nombre = "Juan",
    direccion = {
        ciudad = "Encarnacion",
        barrio = "Centro"
    }
}

Acceso a subcampos

ejemplo.blox
ciudad = personas[1].direccion.ciudad

o también:

ejemplo.blox
ciudad = personas[1]["direccion"]["ciudad"]

Modificar subcampos

ejemplo.blox
personas[1].direccion.barrio = "San Roque"

Propiedades y métodos frecuentes

.dim — cantidad de registros

ejemplo.blox
NUMERICO cantidad

cantidad = personas.dim

.CLAVES() — nombres de campos de un registro

ejemplo.blox
STRING campos[10]

campos = personas[1].CLAVES()

CLAVES(registro)

ejemplo.blox
STRING campos[10]

campos = CLAVES(personas[1])

CLAVES_INFO(registro)

Devuelve una tabla con información más completa sobre los campos del registro:

  • nombre
  • tipo
  • si es subtabla
  • nivel
ejemplo.blox
TABLA info

info = CLAVES_INFO(personas[1])
IMPRIMIR(info[1])

ES_CAMPO(registro, campo)

Verifica si un campo existe en ese registro.

ejemplo.blox
SI (ES_CAMPO(personas[1], "email")) ENTONCES
    IMPRIMIR(personas[1].email)
FIN_SI

TIPO_DATO(tabla, campo)

Obtiene el tipo de dato asociado a un campo.

ejemplo.blox
STRING tipo

tipo = TIPO_DATO(personas, "edad")
IMPRIMIR(tipo)

Valores típicos:

  • NUMERICO
  • STRING
  • LOGICO
  • TABLA
  • NO_EXISTE
  • DESCONOCIDO

Operaciones frecuentes con tablas

Agregar un registro

ejemplo.blox
AGREGAR(personas, { nombre = "Santiago", edad = 33 })

Agregar un campo a toda la tabla

ejemplo.blox
AGREGAR(personas, "email")

Agregar un campo a un solo registro

ejemplo.blox
AGREGAR(personas[2], "telefono")
personas[2].telefono = "555-123"

Eliminar un campo de un registro

ejemplo.blox
ELIMINAR(personas[2], "telefono")

Eliminar un registro

ejemplo.blox
ELIMINAR(personas[2])

Eliminar un registro por índice

ejemplo.blox
ELIMINAR(personas, 2)

Vaciar una tabla

ejemplo.blox
ELIMINAR(personas)

Ejemplo completo

ejemplo.blox
TABLA personas
STRING campo

personas = {
    nombre = "Carlos",
    edad = 30,
    ciudad = "Asuncion"
}

personas = {
    nombre = "Roberto",
    ciudad = "Concepcion"
}

campo = "email"
personas[2][campo] = "rob@mail.com"

IMPRIMIR(personas[1])
IMPRIMIR(personas[2])

Salida esperada:

ejemplo.blox
{
    nombre = "Carlos",
    edad = 30,
    ciudad = "Asuncion"
}

{
    nombre = "Roberto",
    ciudad = "Concepcion",
    email = "rob@mail.com"
}

Buenas prácticas

  • Usa ES_CAMPO() cuando quieras evitar la creación automática de campos.
  • Usa CLAVES() o CLAVES_INFO() para explorar registros heterogéneos.
  • Usa TIPO_DATO() cuando una función de tabla deba soportar varios tipos.
  • Si trabajas con subtablas, valida primero su existencia antes de acceder a campos internos.
  • Si vas a exportar a CSV o JSON, recuerda que no todos los registros tienen por qué compartir exactamente los mismos campos.

Errores frecuentes

1. Confundir edad con Edad

Los nombres de campo son sensibles al texto exacto.

ejemplo.blox
personas[1].edad = 21
personas[1].Edad = 23

Eso crea dos campos distintos:

  • edad
  • Edad

2. Asumir que todos los registros tienen todos los campos

Esto puede fallar en tablas heterogéneas:

ejemplo.blox
IMPRIMIR(personas[3].edad)

Si no estás seguro, protege con:

ejemplo.blox
SI (ES_CAMPO(personas[3], "edad")) ENTONCES
    IMPRIMIR(personas[3].edad)
FIN_SI

3. Confundir la tabla completa con un registro

  • personas es la tabla completa
  • personas[1] es un registro
  • personas[1].nombre es un campo del registro

Relación con JSON

Las tablas BLOX se parecen mucho a estructuras tipo JSON.

Por eso existen funciones como:

  • JSON_A_TABLA()
  • TABLA_A_JSON()
  • TABLA_A_STRING()
  • STRING_A_TABLA()

Estas funciones permiten convertir entre texto estructurado y tablas BLOX de forma muy natural.

Persistencia con SQLite

Una TABLA no solo sirve para trabajar con datos en memoria.
Tambien puede volverse persistente usando SQLite.

Las dos funciones clave son:

  • sqlite.importar(db, "tabla_destino", tabla)
  • tabla = sqlite.exportar(db, "SELECT ...")

Con esto puedes:

  • guardar una tabla entre ejecuciones
  • recuperar sus registros mas adelante
  • consultar los datos con SQL
  • combinar BLOX y SQLite en un mismo flujo de trabajo

Ejemplo conceptual:

ejemplo.blox
INCLUIR "sqlite.api"

SQLITE db
TABLA personas, out

personas = { nombre = "Ana", edad = 28 }
personas = { nombre = "Luis", edad = 35 }

db = sqlite.abrir("personas.db")

sqlite.importar(db, "personas", personas)
out = sqlite.exportar(db, "SELECT nombre, edad FROM personas ORDER BY nombre;")

sqlite.cerrar(db)

Para una explicacion completa del tipo SQLITE y de la API de base de datos, consulta el documento Bases de Datos.