Невозможно использовать вызов функции в функции защиты - PullRequest
9 голосов
/ 11 февраля 2010

Я новичок в Erlang и пытаюсь запрограммировать программу с ограниченным буфером. Это почти работает, за исключением того, что производители не слишком забегают вперед и перезаписывают неиспользованные данные. Чтобы справиться с этим, я решил попробовать установить предохранители в моей функции buffer (), чтобы иметь возможность использовать версию без получения, когда буфер заполнен, версию без отправки, когда буфер пуст, и обычную версия для остального времени.

Моя проблема в том, что защита для версии без получателя требует, чтобы я знал размер массива, представляющего буфер, который требует вызова array:size/1. По-видимому, Erlang не разрешает вызовы функций у охранников, что мешает этому работать. Есть ли способ обойти это без изменения объявления функции для моего буфера актера?

%% 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.

Ответы [ 2 ]

13 голосов
/ 11 февраля 2010

В защите могут использоваться только определенные функции, см. Последовательности защиты в руководстве по Erlang . Вы можете легко сделать то, что вам нужно, следующим образом:

buffer(Buf, NextWrite, NextRead) -> buffer(Buf, NextWrite, NextRead, array:size(Buf)).

buffer(Buf, NextWrite, NextRead, _) when NextWrite == NextRead -> 
  ;
buffer(Buf, NextWrite, NextRead, BufSize) when (NextWrite - NextRead) == BufSize ->
  ;
buffer(Buf, NextWrite, NextRead, _) ->
  .
1 голос
/ 28 июля 2013

Как уже упоминал Джефф Риди, в охранниках допускается всего несколько БИФов.

Но библиотека преобразования синтаксического анализа guardian может использоваться для вызова любой функции в страже.

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