Cuando trabajamos con Elixir y necesitamos manejar datos estructurados, como una lista de empleados, es fundamental organizar nuestro código para facilitar la transformación y almacenamiento de esa información. Para ello, podemos aprovechar la flexibilidad que nos ofrece Elixir con sus módulos y submódulos, y combinarlo con la manipulación de JSON para guardar datos en archivos.
Primero, podemos definir un submódulo dentro de un módulo principal, por ejemplo, Empresa.Empleado. En este submódulo declaramos una estructura con los campos que nos interesan, como nombre, posición y sueldo. Esto nos permite crear instancias claras y tipadas de empleados:
defmodule Empresa do
defmodule Empleado do
defstruct nombre: nil, posicion: nil, sueldo: nil
end
end
Con esta estructura, podemos crear empleados fácilmente, por ejemplo:
empleado = %Empresa.Empleado{nombre: "Dani", posicion: "Desarrolla", sueldo: 30000}
Para gestionar la escritura de estos empleados en formato JSON, podemos crear otro módulo, Empresa.Writer, donde agruparemos funciones relacionadas con la conversión y almacenamiento. En Elixir, podemos definir módulos anidados usando la sintaxis con puntos, como Empresa.Writer, lo que nos da un espacio de nombres organizado sin necesidad de que los archivos o carpetas reflejen esta estructura.
Dentro de Empresa.Writer, una función clave es toMap, que convierte una estructura Empleado en un mapa. Usamos pattern matching para asegurarnos de que recibimos un empleado con los campos esperados y devolvemos un mapa con esos datos. Si la entrada no cumple, devolvemos nil para indicar un error o dato inválido:
defmodule Empresa.Writer do
def toMap(%Empresa.Empleado{nombre: nombre, posicion: posicion, sueldo: sueldo}) do
%{nombre: nombre, posicion: posicion, sueldo: sueldo}
end
def toMap(_), do: nil
end
Luego, para convertir ese mapa a JSON, podemos usar la función toJson, que llama a JSON.encode! (asumiendo que tenemos el paquete JSON instalado). Aquí simplificamos y asumimos que la codificación siempre funciona, aunque en un entorno real sería mejor manejar posibles errores:
defmodule Empresa.Writer do
# ... toMap definido anteriormente ...
def toJson(data) do
JSON.encode!(data)
end
end
Finalmente, para guardar el JSON en un archivo, creamos una función dump que recibe una cadena y la escribe en un archivo usando File.write/2. Esta función devuelve :ok si la operación fue exitosa o una tupla con el error en caso contrario:
defmodule Empresa.Writer do
# ... toMap y toJson definidos anteriormente ...
def dump(json_string) do
File.write("empleados.json", json_string)
end
end
Para facilitar el uso de estas funciones, podemos crear una función pública write que reciba una lista de empleados, los transforme a mapas, filtre los que sean válidos (no nil), los convierta a JSON y finalmente los guarde en el archivo. Usamos pipelines para encadenar estas operaciones de forma clara y concisa:
defmodule Empresa.Writer do
# ... funciones anteriores ...
def write(empleados) do
empleados
|> Enum.map(&toMap/1)
|> Enum.filter(&(&1 != nil))
|> toJson()
|> dump()
end
end
Probando este sistema, podemos crear varios empleados y llamar a Empresa.Writer.write/1 con la lista. Si todo funciona correctamente, se generará un archivo empleados.json con la representación JSON de los empleados válidos.
Este enfoque nos muestra cómo organizar el código en Elixir usando módulos y submódulos, cómo transformar estructuras en mapas para facilitar la codificación JSON, y cómo manejar la escritura en archivos con funciones del módulo File. Además, el uso de pipelines hace que el flujo de datos sea claro y expresivo, facilitando la lectura y mantenimiento del código.