ict1991
ict1991

Reputation: 2110

How do you accept a string in Erlang?

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

Answers (3)

rvirding
rvirding

Reputation: 20926

There are a number of points I would like to make here:

  • The 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.
  • As @AlexeyRomanov mentioned, io:get_line/1 might be a better choice for input.
  • The 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.
  • You spawn the function 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

Alexey Romanov
Alexey Romanov

Reputation: 170899

Use io:get_line("Yes/No> ") instead.

Upvotes: 0

user425720
user425720

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

Related Questions