aprendiendo ( Erlang ).

miércoles, 23 de marzo de 2011

Registros

| 2 comentarios |

Se trata de una estructura para almacenar un número fijo de elementos (como vimos en tipos básicos). Los elementos son llamados de forma similar a las struct's de C. Se declaran de la siguiente forma -record(nombre,{campo1, campo2, ..., campoN}).
Creo que este tipo se ve mucho más claro con un ejemplo:
-module(registro).

-export([new/3, new2/3, new3/0, get_apellidos/1, get_apellidos2/1, equals/2]).
-record(persona, {apellidos="Sin apellidos", nombre="Sin nombre", edad=0, algo}).

new(Apellidos, Nombre, Edad)  ->
    #persona{apellidos=Apellidos, nombre=Nombre, edad=Edad, algo=undefined}.

new2(Apellidos, Nombre, Edad) ->
    {persona, Apellidos, Nombre, Edad, undefined}.

new3() ->
    #persona{}.
    
get_apellidos( #persona{apellidos=Apellidos} ) ->
    Apellidos.

get_apellidos2( {persona, Apellidos, _, _} ) ->
    Apellidos.

equals(Persona1, Persona2) ->
    Persona1 =:= Persona2.
Hemos definido un módulo que usa un registro persona el cual tiene cuatro campos con valores por defecto.
Un registro, una vez compilado, se traduce a una tupla en la que el primer elemento es un átomo con el nombre del registro. En el módulo registro, la función new crea un registro del tipo persona y new2 crea una tupla, pues bien, podemos demostrar que lo anteriormente dicho es cierto comprobando lo en la consola.
1> c(registro).
{ok,registro}
2> P1 = registro:new ("apellido1 apellido2", "nombre", 25).
{persona,"apellido1 apellido2","nombre",25}
3> P2 = registro:new2 ("apellido1 apellido2", "nombre", 25).  
{persona,"apellido1 apellido2","nombre",25}
4> P1 =:= P2.
true
También podíamos haber utilizado la función equals.
5> registro:equals(P1, P2).
true
En la función new3 creamos un registro del tipo persona con los valores por defecto. Si no se estable valores por defecto es undefined.
6> P0 = registro:new3().                               
{persona,"Sin apellidos","Sin nombre",0,undefined}
Para acceder a los datos siempre echamos mano del pattern matching. Las funciones get_apellidos y get_apellidos2 nos permite acceder al apellido de dos formas distintas una a través del uso del registro o de la tupla.
7> registro:get_apellidos(P1). 
"apellido1 apellido2"
8> registro:get_apellidos2(P1).
"apellido1 apellido2"

Registros vs. tuplas

Pero ... ¿qué ventajas nos proporcionan los registros con respecto a las tuplas?
  1. Podemos crear o acceder a los datos sin preocuparnos del orden.
  2. Podemos definirlos en ficheros de inclusión o de cabecera (.hrl) e importarlo en distintos módulos.
  3. Nos permite cambios rápidos en una aplicación como consecuencia del punto anterior.

Publicar un comentario en la entrada

2 comentarios:

  1. Abelardo León González dijo...

    Hola:

    Estoy haciendo un sencillo programa en donde declaro un registro llamado 'punto' que tiene dos campos: coordX e coordY, ambos inicializados a 0.

    A continuación, defino la función 'new' a la cual le paso dos parámetros, X e Y, que devuelve un objeto del tipo de ese registro: {punto, X, Y}.

    La invocación la hago así:
    punto1 = registros:new(3,2).

    La salida es:
    ** exception error: no match or right hand side value {punto, 3, 2}.

    ¿Alguien sabe por qué me sale este mensaje de error? ¿Qué estoy haciendo mal?

    Gracias por la ayuda.

  2. Abelardo León González dijo...

    Hola:

    He copiado este mismo código y ejecutado la primera instrucción:
    c(registros).

    y me ha dado este error:
    registros.erl: no such file or directory
    error.

    A continuación, escribí:
    P1=registros:new("apellido1 apellido2", "nombre", 25).

    y no lo pude ejecutar.


    Lo estoy haciendo desde el Eclipse.

    Si alguien tuviera una idea de cómo solucionarlos, lo agradecería.

    Saludos.

 
Licencia Creative Commons
Aprendiendo Erlang por Verdi se encuentra bajo una Licencia Creative Commons Atribución-NoComercial-CompartirIgual 3.0 Unported.