Как вы принимаете строку в Erlang? - PullRequest
1 голос
/ 16 ноября 2011

Я пишу программу, в которой пользователь должен ввести значение «да» или «нет».Ниже приведен код, который будет выполняться при получении сообщения {createPatient, PatientName}.

{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);

При выполнении отображается строка «Новый пациент с именем ...», однако строка Да /Нет не отображается, и программа как бы вылетает, потому что, если отправлено другое сообщение, выполнение этого сообщения не произойдет.Есть ли другой способ решить эту проблему, пожалуйста?

Ответы [ 3 ]

3 голосов
/ 17 ноября 2011

Я хотел бы отметить несколько моментов:

  • Функция io:read/1 читает термин, а не просто строку, поэтому вы должны завершить ввод с помощью '.'(как в оболочке).
  • io:read/1 возвращает {ok,Term} или {error,Reason} или eof, поэтому код должен проверить эти значения, например, с помощью case.
  • Как заметил @AlexeyRomanov, io:get_line/1 может быть лучшим выбором для ввода.
  • Выражение if должно обрабатывать все случаи, даже те, в которых вы ничего не хотите делать, иначе вы получитеошибка.Это может быть объединено с case проверкой значения чтения.
  • Вы вызываете функцию patient:newPatient/1 до и спрашиваете, является ли имя новым пациентом, это кажется немного странным.Что делает функция newpatient?Это в любом случае также делает io для пользователя, который может мешать функциям здесь?

Основная проблема, кажется, выяснить, что делается, где и когда.

1 голос
/ 16 ноября 2011

Это очень искусственная проблема.В эрланге любое общение обычно является межпроцессным, и обмен строками не имеет никакого смысла - вы задаете вопрос в контексте процесса А, и вы хотите разместить ответ в контексте процесса В (вероятно, оболочки).

В любом случае, подумайте над тем, чтобы задать вопрос и подождать в блоке получения, чтобы получить ответ.Когда вопрос появляется в оболочке, вызовите функцию, которая отправит ответ «запрашивающему» процессу с вашим ответом.

Итак:

io:format("*--- New Patient with name - ~w~n", [PatientName]),
receive
  {answer, yes} -> do_something();
  {answer, no} -> do_something()
end

Функция «отвечая» будет выглядеть так:

answer(PatientName, Answer) ->
   PatientName ! {answer, Answer}.

И действие оболочки:

$> *--- New Patient with name - User1036032
$> somemodule:answer('User1036032', yes).

Можно создать некоторый диалог с оболочкой (даже оболочкой Unix), но, если честно, он используется настолько редко, что я делаюне помню тех приемов ввода / вывода с чтением и записью.http://trapexit.com/ имел обыкновение иметь поваренную книгу с этим материалом.

0 голосов
/ 17 ноября 2011

Вместо этого используйте io:get_line("Yes/No> ").

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...