Note that there are some explanatory texts on larger screens.

plurals
  1. POErlang/OTP behaviors for beginner
    primarykey
    data
    text
    <p>As I understood from the "Erlang and OTP in action" book, the word behavior refers to:</p> <ul> <li>the behaviour interface, which is a set of functions;</li> <li>the behaviour implementation, which is the application-specific code (a callback module);</li> <li>the behaviour container, which is a process.</li> </ul> <p><strong>Question:</strong></p> <p><em>What an Erlang/OTP beginner should know about behaviours? Is it possible to describe and understand the notion of OTP behaviour in a nutshell?</em></p> <p><em>What 'callback function' does actually mean in the context of Elang/OTP?</em></p> <p>Can we consider the callbacks in a behaviour implemenation as methods overriden in Java?</p> <p>The book says that the associated callback function for the library function 'gen_server:start_link/4' in the following code is 'Module:init/1'.</p> <p>Does that mean that with init/1 we call the gen_server:start_link/4 library function? Or does that mean anything else?</p> <pre><code>-module(tr_server). -behaviour(gen_server). -include_lib("eunit/include/eunit.hrl"). %% API -export([ start_link/1, start_link/0, get_count/0, stop/0 ]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -define(SERVER, ?MODULE). -define(DEFAULT_PORT, 1055). -record(state, {port, lsock, request_count = 0}). %%%=================================================================== %%% API %%%=================================================================== %%-------------------------------------------------------------------- %% @doc Starts the server. %% %% @spec start_link(Port::integer()) -&gt; {ok, Pid} %% where %% Pid = pid() %% @end %%-------------------------------------------------------------------- start_link(Port) -&gt; gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []). %% @spec start_link() -&gt; {ok, Pid} %% @doc Calls `start_link(Port)' using the default port. s tart_link() -&gt; start_link(?DEFAULT_PORT). %%-------------------------------------------------------------------- %% @doc Fetches the number of requests made to this server. %% @spec get_count() -&gt; {ok, Count} %% where %% Count = integer() %% @end %%-------------------------------------------------------------------- get_count() -&gt; gen_server:call(?SERVER, get_count). %%-------------------------------------------------------------------- %% @doc Stops the server. %% @spec stop() -&gt; ok %% @end %%-------------------------------------------------------------------- stop() -&gt; gen_server:cast(?SERVER, stop). %%%=================================================================== %%% gen_server callbacks %%%=================================================================== init([Port]) -&gt; {ok, LSock} = gen_tcp:listen(Port, [{active, true}]), {ok, #state{port = Port, lsock = LSock}, 0}. handle_call(get_count, _From, State) -&gt; {reply, {ok, State#state.request_count}, State}. handle_cast(stop, State) -&gt; {stop, normal, State}. handle_info({tcp, Socket, RawData}, State) -&gt; do_rpc(Socket, RawData), RequestCount = State#state.request_count, {noreply, State#state{request_count = RequestCount + 1}}; handle_info(timeout, #state{lsock = LSock} = State) -&gt; {ok, _Sock} = gen_tcp:accept(LSock), {noreply, State}. terminate(_Reason, _State) -&gt; ok. code_change(_OldVsn, State, _Extra) -&gt; {ok, State}. %%%=================================================================== %%% Internal functions %%%=================================================================== do_rpc(Socket, RawData) -&gt; try {M, F, A} = split_out_mfa(RawData), Result = apply(M, F, A), gen_tcp:send(Socket, io_lib:fwrite("~p~n", [Result])) catch _Class:Err -&gt; gen_tcp:send(Socket, io_lib:fwrite("~p~n", [Err])) end. split_out_mfa(RawData) -&gt; MFA = re:replace(RawData, "\r\n$", "", [{return, list}]), {match, [M, F, A]} = re:run(MFA, "(.*):(.*)\s*\\((.*)\s*\\)\s*.\s*$", [{capture, [1,2,3], list}, ungreedy]), {list_to_atom(M), list_to_atom(F), args_to_terms(A)}. args_to_terms(RawArgs) -&gt; {ok, Toks, _Line} = erl_scan:string("[" ++ RawArgs ++ "]. ", 1), {ok, Args} = erl_parse:parse_term(Toks), Args. %% test start_test() -&gt; {ok, _} = tr_server:start_link(1055). </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload