Exercício simultâneo de curso Erlang: Minha resposta pode ser melhorada?
Eu estou fazendo este exercício docurso erlang.org:
2) Escreva uma função que inicie N processos em um anel e envie uma mensagem M vezes em torno de todos os processos no anel. Após o envio das mensagens, os processos devem terminar normalmente.
Aqui está o que eu vim com:
-module(ring).
-export([start/2, node/2]).
node(NodeNumber, NumberOfNodes) ->
NextNodeNumber = (NodeNumber + 1) rem NumberOfNodes,
NextNodeName = node_name(NextNodeNumber),
receive
CircuitNumber ->
io:format("Node ~p Circuit ~p~n", [NodeNumber, CircuitNumber]),
LastNode = NodeNumber =:= NumberOfNodes - 1,
NextCircuitNumber = case LastNode of
true ->
CircuitNumber - 1;
false ->
CircuitNumber
end,
if
NextCircuitNumber > 0 ->
NextNodeName ! NextCircuitNumber;
true ->
ok
end,
if
CircuitNumber > 1 ->
node(NodeNumber, NumberOfNodes);
true ->
ok
end
end.
start(NumberOfNodes, NumberOfCircuits) ->
lists:foreach(fun(NodeNumber) ->
register(node_name(NodeNumber),
spawn(ring, node, [NodeNumber, NumberOfNodes]))
end,
lists:seq(0, NumberOfNodes - 1)),
node_name(0) ! NumberOfCircuits,
ok.
node_name(NodeNumber) ->
list_to_atom(lists:flatten(io_lib:format("node~w", [NodeNumber]))).
Aqui está a sua saída:
17> ring:start(3, 2).
Node 0 Circuit 2
ok
Node 1 Circuit 2
Node 2 Circuit 2
Node 0 Circuit 1
Node 1 Circuit 1
Node 2 Circuit 1
Se eu realmente conhecesse Erlang, eu poderia fazer diferente para melhorar esse código? E especificamente:
Existe alguma alternativa para especificar uma cláusula "true" do-nothing nas duas últimas declarações if?
Estou realmente terminando graciosamente? É necessária alguma ação especial ao finalizar um processo que foi registrado?