How to save state in an Erlang process?
erlang
Solution
Simple solution, you can pass to your function `is_member_loop(Data_file)` the list of numbers rather then the file name.
The best solution when you deal with a state consists in using a gen_server. To learn more you should take a look at records and gen_server behaviour (this may also be useful).
In practice:
1) start with a module (yourmodule.erl) based on gen_server behaviour 2) read your file in the init function of the gen_server and pass it as state field:
init([]) ->
Numbers = read_numbers(Data_file),
{ok, #state{numbers=Numbers}}.
3) write a function which will be used to trigger a call to the gen_server
check_number(Number) ->
gen_server:call(?MODULE, {check_number, Number}).
4) write the code in order to handle messages triggered from your function
handle_call({check_number, Number}, _From, #state{numbers=Numbers} = State) ->
Reply = lists:member(Number, Numbers)},
{reply, Reply, State};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
5) export from yourmodule.erl function `check_number`
-export([check_number/1]).
Two things to be explained about point 4:
a) we extract values inside the record State using pattern matching
b) As you may see I left the generic handle call, otherwise your gen_server will fail due to wrong pattern matching whenever a message different from {check_number, Number} is received
Note: if you are new to erlang, don't use process dictionary
Problem
I am learning Erlang and trying to figure out how I can, and should, save state inside a process. For example, I am trying to write a program that given a list of numbers in a file, tells me whether a number appears in that file. My approach is to uses two processes cache which reads the content of the file into a set, then waits for numbers to check, and then replies whether they appear in the set. ``` is_member_loop(Data_file) -> Numbers = read_numbers(Data_file), receive {From, Number} -> From ! {self(), lists:member(Number, Numbers)}, is_member_loop(Data_file) end. ``` client which sends numbers to cache and waits for the `true` or `false` response. ``` check_number(Number) -> NumbersPid ! {self(), Number}, receive {NumbersPid, Is_member} -> Is_member end. ``` This approach is obviously naive since the file is read for every request. However, I am quite new at Erlang and it is unclear to me what would be the preferred way of keeping state between different requests. Should I be using the process dictionary? Is there a different mechanism I am not aware of for that sort of process state? Update The most obvious solution, as suggested by user601836, is to pass the set of numbers as a param to `is_member_loop` instead of the filename. It seems to be a common idiom in Erlang and there is a good example in the fantastic online book Learn you some Erlang. I think, however, that the question still holds for more complex state that I'd want to preserve in my process.