我正在打这个电话:
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}.
怎么了?
答案 0 :(得分:3)
在使用gen_server
行为的模块中,handle_call
回调函数应该使用三个参数。但是,您已定义了两个不同的功能handle_call/2
和handle_call/3
。 (在Erlang中,具有相同名称但使用不同数量的参数的函数被视为不同的函数。)
由于gen_server
模块只查找handle_call/3
并忽略handle_call/2
,因此始终会调用“undef”函数。
要解决此问题,请更改函数以获取(忽略的)第二个参数,并将请求放在第一位,将状态放在最后:
handle_call({add, Login, Pass, Role}, _From, State) ->
并将end.
更改为end;
- .
分隔不同的函数,而;
分隔同一函数的不同子句。
答案 1 :(得分:2)
行为似乎有效,
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
干杯!