Ошибка при трансляции сообщения процессам в Erlang

Я новичок в Erlang, и я пытаюсь заставить PID отправить сообщение нескольким другим PID.

У меня есть функция, которая принимает в качестве аргументов Pid, ​​строку (сообщение) и целое число R (радиус).

broadcast(P, M, R) ->
  P ! {self(), friends},
  receive
    {P, Friends} ->
      [F ! {{broadcast, P, M, R}, Friends} || F <- Friends],
      ok;
    {} ->
  end.

У меня есть эта функция прослушивателя, которая ожидает получения новых сообщений:

looper({Name, Friends, Messages}) ->
  receive
    {From, friends} ->
       From ! {self(), Friends},
       looper({Name, Friends, Messages});
    {{broadcast, ID, M, R}, Friends}  ->
       % From ! {From, {self(), {ID, M}}},
       looper({Name, Friends, [{ID, M} | Messages]});
    terminate ->
      ok
  end.

Когда я вызываю широковещательную функцию, я получаю это сообщение:

faceinsok:broadcast(Pid, "asd", 1).                     
** exception error: bad argument
     in function  faceinsok:'-broadcast/3-lc$^0/1-0-'/5 (faceinsok.erl, line 56)

строка 56 это строка:

[F ! {{broadcast, P, M, R}, Friends} || F <- Friends],

Насколько я понимаю, я неправильно передаю сообщение: / Что я делаю неправильно?


person sokras    schedule 05.10.2014    source источник
comment
возможный дубликат Как передать сообщение в список процессов в Erlang? Консоль висит   -  person mpm    schedule 05.10.2014
comment
Улучшен код другого сообщения об ошибке, поэтому я не думаю, что его можно рассматривать как дубликат.   -  person sokras    schedule 05.10.2014
comment
У вас нет проблемы с широковещательной передачей, у вас проблемы с сопоставлением шаблонов/типом.   -  person zxq9    schedule 05.10.2014


Ответы (1)


Очередной раз. В строке 55 вы получаете {P, Friends} и предполагаете, что Friends — это список. Но я предполагаю, что это не так, так как в строке 53 вы отправляете {self(), friends}. И вы не можете составить список для атома friends.

Вы должны добавить проверку безопасности, если Friends на самом деле является списком.

  receive
    {P, Friends} when is_list(Friends) ->
      [F ! {{broadcast, P, M, R}, Friends} || F <- Friends],
      ok;
    {} ->

а затем проверьте, работает ли он так, как вы думаете.

person mpm    schedule 05.10.2014
comment
На самом деле Friends — это всегда список. В строке 53 я отправляю сообщение со строкой friends, лупер получает это и отправляет обратно список Friends. Я делаю это не так? :/ - person sokras; 05.10.2014
comment
Вы думаете, что это список (Пидов), или это должен быть список. Попробуйте вывести его непосредственно перед строкой 56 и посмотрите, что это такое, как в простейшей отладке. - person mpm; 05.10.2014
comment
Это должен быть список {Pid, String}. Может быть, я не делаю правильное сопоставление шаблона? - person sokras; 05.10.2014
comment
Что вы имеете в виду под String ? И, пожалуйста, просто проверьте фактическое значение переменной, это самый простой способ сделать это. - person mpm; 05.10.2014
comment
@mpm: Проблема, конечно, в Friends, который не является списком, но тот факт, что friends является атомом, не имеет к этому никакого отношения. В остальном ваш ответ правильный. - person aronisstav; 06.10.2014