Reputation: 2110
I'm writing a program where the user must enter a 'yes' or 'no' value. The following is the code that will be executed when the message {createPatient,PatientName} is received.
{createPatient, PatientName} ->
Pid = spawn(patient,newPatient,[PatientName]),
register(PatientName,Pid),
io:format("*--- New Patient with name - ~w~n", [PatientName]),
Result = io:read("Yes/No> "),
{_,Input} = Result,
if(Input==yes) ->
io:format("OK")
end,
loop(PatientRecords, DoctorPatientLinks, DoctorsOnline, CurrentPatientRequests, WaitingOfflineDoctorRequests);
When executed ,the line "New Patient with name..." is displayed however the line Yes/No is not displayed and the program sort of crashes because if another message is sent, then the execution of that message will not occur. Is there a different way to solve this problem please?
Upvotes: 2
Views: 2228
Reputation: 20926
There are a number of points I would like to make here:
io:read/1
function reads a term, not just a line, so you have to terminate input with a '.' (like in the shell).io:read/1
returns {ok,Term}
or {error,Reason}
or eof
so you code should check for these values, for example with a case
.io:get_line/1
might be a better choice for input.if
expression must handle all cases even the ones in which you don't want to do anything, otherwise you will get an error. This can be combined with the case
testing the read value.patient:newPatient/1
before you ask if the name is a new patient, this seems a little strange. What does the newpatient
function do? Is it in anyway also doing io to the user which might be interfering with functions here?The main problem seems to be work out what is being done where, and when.
Upvotes: 3
Reputation: 3598
This is very artificial problem. In erlang any communication is usually inter-process and exchanging strings wouldn't make any sense - you ask question in context of process A and you would like to post answer in context of process B (shell probably).
Anyways, consider asking question and waiting in receive block in order to get an answer. When question pops out in shell, call a function which will send the answer to 'asking' process with your answer.
So:
io:format("*--- New Patient with name - ~w~n", [PatientName]),
receive
{answer, yes} -> do_something();
{answer, no} -> do_something()
end
The 'answering' function would look like that:
answer(PatientName, Answer) ->
PatientName ! {answer, Answer}.
And shell action:
$> *--- New Patient with name - User1036032
$> somemodule:answer('User1036032', yes).
It is possible to create some dialog with shell (even unix shell), but to be honest it is used so rare that I do not remember those I/O tricks with read and write. http://trapexit.com/ used to have cookbook with this stuff.
Upvotes: 1