Основной вопрос Эрланга - PullRequest
2 голосов
/ 18 декабря 2010

Я пытался выучить Erlang и наткнулся на код, написанный Джо Армстронгом:

start() ->
    F = fun interact/2,
    spawn(fun() -> start(F, 0) end).

interact(Browser, State) ->
    receive
        {browser, Browser, Str} ->
            Str1 = lists:reverse(Str),
            Browser ! {send, "out ! " ++ Str1},
            interact(Browser, State);
    after 100 ->
        Browser ! {send, "clock ! tick " ++ integer_to_list(State)},
        interact(Browser, State+1)
end.

Это сообщение из блога об использовании веб-сокетов с Erlang: http://armstrongonsoftware.blogspot.com/2009/12/comet-is-dead-long-live-websockets.html

Может кто-нибудь объяснить мне, почему в функции start он запускает анонимную функцию start (F, 0), когда start - это функция, которая принимает нулевые аргументы.Я не понимаю, что он пытается здесь сделать.

Ответы [ 3 ]

5 голосов
/ 18 декабря 2010

Далее в этом посте (листинги) вы можете увидеть, что есть другая функция (start / 2), которая принимает два аргумента:

start(F, State0) ->
{ok, Listen} = gen_tcp:listen(1234, [{packet,0},
                                  {reuseaddr,true},
                                  {active, true}]),
par_connect(Listen, F, State0).

Пример кода, который вы процитировали, был только отрывком, гдефункция была опущена для простоты.

3 голосов
/ 18 декабря 2010

Причина появления fun таким образом состоит в том, чтобы избежать необходимости экспортировать функцию, предназначенную только для внутреннего использования. Одна из проблем заключается в том, что все экспортированные функции доступны всем пользователям, даже если они предназначены только для внутреннего использования. Одним из примеров этого является модуль обратного вызова для gen_server, который обычно содержит как экспортированный API для клиентов, так и функции обратного вызова для поведения gen_server. Функции обратного вызова предназначены только для вызова по поведению gen_server, а не для других, но они видны в списке экспорта и не блокируются в любом случае.

порождение fun уменьшает количество экспортируемых внутренних функций.

1 голос
/ 18 декабря 2010

В Erlang функции идентифицируются по их имени и их arity (количество параметров, которые они принимают). Вы можете иметь более одной функции с одинаковым именем, если у них у всех разное количество параметров. Две функции, которые вы разместили выше: start/0 и interact/2. start/0 не называет себя; вместо этого он вызывает start/2, и если вы посмотрите вниз на страницу, на которую вы ссылаетесь, вы найдете определение start/2.

Смысл использования spawn таким образом - запустить серверный процесс в фоновом режиме и вернуть управление вызывающей стороне. Чтобы поиграть с этим кодом, я предполагаю, что вы запустите интерпретатор Erlang, загрузите скрипт и затем вызовете функцию start/0. Этот метод затем запустит процесс в фоновом режиме и вернется, чтобы вы могли продолжить вводить в интерпретатор Erlang.

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