I'm completely new to Elixir but had to use Erlang for a piece of coursework and I am currently trying to line by line translate it to Elixir.
I have it compiling successfully and everything seems good to go. I want to start a server process using the start_server()
function, which spawns a server on a new process and then send it a message from iex:
def server(s, us, sums, n) do
IO.puts("Server online")
receive do
:finished ->
:ok
%... More message patterns
end
end
end
def start_server() do
server_pid = spawn(server(0, 0, [], 0))
Process.register(server_pid,:server)
IO.puts("server started and registered. Should be waiting for message")
end
However, when running start_server in iex, it seems to be stuck waiting for a message, not allowing me to send any more commmands, unlike what I'm used to in Eshell. I looked online for simple examples of this same scenario (spawning a process that is waiting for messages) and found this "Salutator" example, but following it's instructions lead to the same issue. Is there something simple that I am missing?
When using spawn
, you need to pass it a function to run, like one of these two:
spawn(fn -> IO.puts("hi from pid #{inspect(self())}")
spawn(&MyModule.print_my_pid/0)
What you're doing is the equivalent of this:
IO.inspect(self())
spawn(IO.inspect(self()))
# This code prints:
#PID<0.108.0>
#PID<0.108.0>
** (ArgumentError) errors were found at the given arguments:
* 1st argument: not a fun
:erlang.spawn(#PID<0.108.0>)
iex:6: (file)
As you can see, both the self()
calls had the same PID - they both ran on the parent process. Then, spawn
was called with the output of that, which is not a function and thus invalid.
What you want here is probably to wrap the server
call in an anonymous function:
server_pid = spawn(fn -> server(0, 0, [], 0) end)