2

私はこの電話をかけています:

add(Login, Pass, Role) ->
  gen_server:call(?SERVER, {add, Login, Pass, Role}).

そして、私はそれが以下と一致することを期待しています:

handle_call(State, {add, Login, Pass, Role}) ->
  io:format("add ~n"),
  Db = State#state.db,
  case lists:keyfind(Login, 1, Db) of
    false->
      io:format("add - reg new ~n"),
      {reply, registered, State#state{db=[{Login, erlang:md5(Pass), Role, ""}|Db]}};
     {Key, Result}-> 
      {reply, invalid_params, Db}  
  end.

ただし、常に次のようになります。

handle_call(_Request, _From, State) ->
  io:format("undef ~n"),
  Reply = ok,
  {reply, Reply, State}.

どうしたの?

4

2 に答える 2

3

gen_server動作を使用するモジュールでは、handle_callコールバック関数は 3 つの引数を取る必要があります。ただし、2 つの異なる関数 と を定義handle_call/2handle_call/3ました。(Erlang では、名前が同じでも引数の数が異なる関数は、異なる関数と見なされます。)

gen_serverモジュールは を探してhandle_call/3無視するだけなので、handle_call/2「undef」関数は常に呼び出されます。

これを修正するには、(無視された) 2 番目の引数を取るように関数を変更し、リクエストを最初に、状態を最後に置きます。

handle_call({add, Login, Pass, Role}, _From, State) ->

を変更end.しますend;.は異なる関数を;分離しますが、 は同じ関数の異なる節を分離します。

于 2015-01-20T11:35:34.223 に答える
3

動作は有効に見えますが、

handle_callそのような仕様があります:

-spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()},
    State :: #state{}) ->
  {reply, Reply :: term(), NewState :: #state{}} |
  {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} |
  {noreply, NewState :: #state{}} |
  {noreply, NewState :: #state{}, timeout() | hibernate} |
  {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
  {stop, Reason :: term(), NewState :: #state{}}).

ここを見ることができれば http://erlang.org/doc/man/gen_server.html#Module:handle_call-3

また、otp のデフォルトの動作については、最初はテンプレートを使用するのが最善です。gen_server の例: https://gist.github.com/kevsmith/1211350

乾杯!

于 2015-01-20T10:47:40.133 に答える