Soy nuevo en Erlang y estoy tratando de programar un programa de problema de buffer delimitado. Está casi funcionando, excepto para asegurarse de que los productores no se excedan y sobrescriban datos no consumidos. Para manejar esto, decidí tratar de poner guardias en mi función buffer() para poder tener una versión sin recepción utilizada cuando el buffer está lleno, una versión sin enviar usada cuando el buffer está vacío, y una versión normal versión por el resto del tiempo.No se puede usar la función de llamada en la función de protección
Mi problema es que la protección para la versión sin receptor me exige conocer el tamaño de la matriz que representa el búfer, que requiere una llamada al array:size/1
. Aparentemente, Erlang no permite invocaciones de funciones en guardias, lo que impide que esto funcione. ¿Hay alguna forma de evitar esto sin cambiar la declaración de función para mi actor de búfer?
%% buffer: array num num
%% A process that holds the shared buffer for the producers and consumers
buffer(Buf, NextWrite, NextRead) when NextWrite == NextRead ->
io:format(" * ~w, ~w, ~w~n", [array:to_list(Buf), NextRead, NextWrite]),
receive
{enqueue, Reply_Pid, Num} ->
io:format("~w: > ~w~n", [Reply_Pid, Num]),
buffer(array:set(NextWrite rem array:size(Buf), Num, Buf), NextWrite + 1, NextRead);
finish ->
io:format("finished printing~n")
end;
buffer(Buf, NextWrite, NextRead) when (NextWrite - NextRead) == array:size(Buf) ->
io:format(" * ~w, ~w, ~w~n", [array:to_list(Buf), NextRead, NextWrite]),
receive
{dequeue, Reply_Pid} ->
io:format("~w: < ~w~n", [Reply_Pid, array:get(NextRead rem array:size(Buf), Buf)]),
Reply_Pid ! {reply, array:get(NextRead rem array:size(Buf), Buf)},
buffer(Buf, NextWrite, NextRead + 1);
finish ->
io:format("finished printing~n")
end;
buffer(Buf, NextWrite, NextRead) ->
io:format(" * ~w, ~w, ~w~n", [array:to_list(Buf), NextRead, NextWrite]),
receive
{dequeue, Reply_Pid} ->
io:format("~w: < ~w~n", [Reply_Pid, array:get(NextRead rem array:size(Buf), Buf)]),
Reply_Pid ! {reply, array:get(NextRead rem array:size(Buf), Buf)},
buffer(Buf, NextWrite, NextRead + 1);
{enqueue, Reply_Pid, Num} ->
io:format("~w: > ~w~n", [Reply_Pid, Num]),
buffer(array:set(NextWrite rem array:size(Buf), Num, Buf), NextWrite + 1, NextRead);
finish ->
io:format("finished printing~n")
end.
Eso es bueno, simple y fácil de entender. Gracias. –
Hola @Geoff, ¿conoces una manera de comparar dos cuerdas como guardia? por ejemplo, función cuando string: igual (cadena1, cadena2) -> 1. –
@DenisWeerasiri Estoy bastante seguro de que 'string: igual/2' es lo mismo que' == 'así que puedes usar eso en la guardia . –