[erlang-questions] record type as variable

Allan Wegan <>
Fri Aug 6 01:12:16 CEST 2010


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2010-08-04 19:05, Noel Bush wrote:
> Is there any way to specify the type of a record using a variable? I
> want to be able to do this sort of thing:
>
> create(Type, Name) ->
>     #Type{name = Name}.

No, there isn't (at least no easy one, as i think). But what you can do is:

Use a generic record type with the subtype as an atom field defined in a
common header file.
Build one module for each subtype named as the subtype and containing
all needed methods for using the subtype.
Build one API module that dispatches function calls to the more specific
functions in the subtype modules.

% Generic type specification in the header file that is included in the
API and subtype modules:
- -record('sometype', {
  subtype :: atom(),
  data    :: term()
}).

% Dispatcher functions in API module named 'sometype':
get_name(#sometype{subtype = M} = O) -> M:get_name(O).
set_name(#sometype{subtype = M} = O, Name) -> M:set_name(O, Name).

% Specification of the data in the subtype1 module:
- -record('subtype1_data', {
  property1 :: term(),
  name      :: term(),
  propertyN :: term()
}).

% Functions in 'subtype1' module:
get_name(
  #sometype{subtype = 'subtype1', data = #subtype1_data{name = Name}
) ->
  Name
.
set_name(
  #sometype{subtype = 'subtype1', data = #subtype1_data{} = Data}, Name
) ->
  #sometype{subtype = 'subtype1', data = Data#subtype1_data{name = Name}
.

In regular code you would use something like that to access the name
property:

Name = sometype:get_name(I), % where I is an instance of #sometype{}
with any subtype.
New_i = sometype:set_name(I, Name), % where I is an instance of
#sometype{} with any subtype and name is the new name.


This pattern allows to use records for sets of rather generic types that
share a common API facade. You are obviously not limited to dispatchers
in the API module. It is a convenient place for higher level functions,
that do not have to know the exact implementation of each subtype.

It's a little like abstract classes, interfaces, and their
implementations in OOP - but without any inheritance or other language
support of course... ;)



- -- 
Allan Wegan
Jabber: 
ICQ:    209459114
Phone:  +49 40 6732962
Schöneberger Strasse 60, 22149 Hamburg

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (MingW32)

iQEcBAEBAgAGBQJMW0VQAAoJENm5axHh7AcxdgoH/0+Z+M2OKpy0INS0/cvbTY78
/VLUStFwwrYO52nZgzyRF1/HBZNaQCmihUH+mP2hvLGZf9bicLwXk+pBc+vG6SCL
wyN69/EcNv+gjFhf1db+MSK2i6z4tccl+7Ia8mKhEDDUuc8G9s1/4vIm8Lez8I1R
LtBNNU9D4QdihZsb60TkXOXW5yaEByPiiOBuYzoIw8iKV35Zbpo4Q9PzciIthBmy
O/CME44lU0xLiFnRBHN2lqoNU9F4SB4bFyGKTy2Z7P5j0oy1uqYyh5E71AomDE0j
I9a/Tx4OBizY31lEFlSWDVDXh55GLHVMK7sqkamuLnylIJ6wwz3vKo4WbWPsWFo=
=V80L
-----END PGP SIGNATURE-----


More information about the erlang-questions mailing list