How to receive loop type text in Erlang shell?

Hi all. I asked chatgpt: accept input for only n seconds in erlang and it gave me back:

-module(input_timeout).
-export([start/0, input/1]).
start() ->
    Self = self(),
    Timeout = 5, % 5 seconds timeout
    spawn(fun() -> timer:sleep(Timeout * 1000), Self ! timeout end),
    input(Timeout).
input(Timeout) ->
    io:format("Enter something within ~w seconds: ", [Timeout]),
    receive
        {From, Msg} ->
            From ! {input, Msg}
    after Timeout * 1000 ->
            io:format("~nTime's up!~n"),
            exit(timeout)
    end.

But typing in text does nothing and only shows up after the timeout happens. How do you type input in the erlang shell with this type of code?

1 Like

This is critically missing the “accept input” part of your request. Here’s an alternative that spawns a process that does blocking I/O and communicates the result back to its spawner - unless it’s killed for taking too long to do that.

-module(input_timeout).
-export([start/0, input/2]).

start() ->
    Timeout = 5,
    Pid = spawn(?MODULE, input, [self(), Timeout]),
    receive
        {Pid, Input} ->
            io:fwrite("You typed: ~s\n", [Input])
    after Timeout * 1000 ->
              exit(Pid, timeout),
              io:fwrite("~nTime’s up!~n")
    end.

input(Pid, Timeout) ->
    case io:get_line(io_lib:fwrite("Enter something within ~w seconds: ", [Timeout])) of
        eof -> ok;
        {error, _} -> ok;
        Input -> Pid ! {self(), Input}
    end.
2 Likes

Thanks! I appreciate your assistance!