how to hold lists
Richard A. O'Keefe
ok@REDACTED
Mon May 15 03:06:33 CEST 2006
"Yani Dzhurov" <yani.dzhurov@REDACTED> wrote:
I need these lists to simulate some kind of enumarations.
...
This procedure looks pretty stupid in this example.
But when I have large enums and need to insert new values in it /{Monday,
Tuesday, Wednesday,SOME_OTHER_WEEK_DAY, Thursday, Friday, Saturday=20,
Sunday}/ it would be easy to maintain.
If someone else has a better idea, pls advise me:)
The big question is this:
When you write "I ... need to insert new values ..."
do you mean that *YOU* need to insert new values (perhaps with a
text editor) and then a re-compile is OK,
or that you need a PROGRAM acting perhaps as your agent to do
this at run time?
If it is the former, there is a mantra that I would like you to recite
several times a day:
CODE is DATA!
Let's say you want the following operations on an enumeration:
(1) Return the number of enumerals, N.
(2) Convert from an integer 1..N to the corresponding enumeral.
(3) Convert from an enumeral to the corresponding integer.
(4) Test whether a symbol is a member of the set.
(5) Return all the enumerals in order as a list.
Let's say you would be happy with this as a module
-module(ModuleName).
-export([size/0,from_integer/1,to_integer/1,includes/1,members/0]).
size() -> N.
from_integer(1) -> Enumeral_1;
...
from_integer(N) -> Enumeral_N.
to_integer(Enumeral_1) -> 1;
...
to_integer(Enumeral_N) -> N.
includes(Enumeral_1) -> true;
...
includes(Enumeral_N) -> true;
includes(X) when atom(X) -> false.
members() -> [Enumeral_1, ..., Enumeral_N].
Here are some macro definitions in M4 that do the job:
define(`def_from_int',
`define(`counter',eval(counter+1))from_integer(counter) -> $1`'ifelse($#,1, `.
', `;
def_from_int(shift($@))')')dnl
define(`def_to_int',
`define(`counter', eval(counter+1))to_integer($1) -> counter`'ifelse($#,1, `.
', `;
def_to_int(shift($@))')')dnl
define(`def_inc', `includes($1) -> true;
ifelse($#,1, `includes(X) when atom(X) -> false.
', `def_inc(shift($@))')')dnl
define(`define_enumeration',
`-module($1).
-export([size/0,from_integer/1,to_integer/1,includes/1,members/0]).
size() -> eval($#-1).
define(`counter', 0)def_from_int(shift($@))
define(`counter', 0)def_to_int(shift($@))
def_inc(shift($@))
members() -> [shift($@)].
')dnl
Put that in file enum.m4
Put this example in every.erl.m4:
define_enumeration(every, tom,dick,harry)
(note no square brackets or trailing dot). Run it like this:
m4 enum.m4 every.erl.m4 >every.erl
And what you get is
-module(every).
-export([size/0,from_integer/1,to_integer/1,includes/1,members/0]).
size() -> 3.
from_integer(1) -> tom;
from_integer(2) -> dick;
from_integer(3) -> harry.
to_integer(tom) -> 1;
to_integer(dick) -> 2;
to_integer(harry) -> 3.
includes(tom) -> true;
includes(dick) -> true;
includes(harry) -> true;
includes(X) when atom(X) -> false.
members() -> [tom,dick,harry].
I chose M4 as the simplest and quickest way to do the job.
Of course you could do this in Erlang.
More information about the erlang-questions
mailing list