Erlang基本通用服务器调试器输出解释

时间:2014-10-29 16:47:38

标签: erlang gen-server

我在使用Erlang模块时遇到了一些麻烦。这是我写的那个:

- 模(basic_gen_server)。     -export([start / 1,call / 2,cast / 2])。

start(Module) ->
    register(server, spawn(basic_gen_server,gen_server_loop,[Module, Module:init()])), server.

call(Pid,Request) -> 
    Pid ! {call, self(), Request},
    receive
        Reply -> Reply
    end.

cast(Pid,Request) ->
    Pid ! {cast, self(), Request},
    receive
        _ -> ok
    end.

gen_server_loop(Module, CurrentState) -> 
    io:fwrite("gen_server_loop~n", []),
    receive
        {call, CallPid, Request} -> 
            {reply, Reply, NewState} = Module:handle_call(Request,self(),CurrentState),
            CallPid ! Reply,
            gen_server_loop(Module, NewState);
        {cast, CastPid, Request} ->
            {noReply, NewState} = Module:handle_cast(Request, CurrentState),
            CastPid ! noReply,
            gen_server_loop(Module, NewState)
    end.

以下是定义的回调模块:

% Written by Caleb Helbling
% Last updated Oct 10, 2014

-module(name_server).
-export([init/0, add/3, whereis/2, handle_cast/2,
         handle_call/3, handle_swap_code/1]).

%% client routines

add(ServerPid, Person, Place) ->
    basic_gen_server:cast(ServerPid, {add, Person, Place}).

whereis(ServerPid, Person) ->
    basic_gen_server:call(ServerPid, {whereis, Person}).

%% callback routines

init() ->
    maps:new().

handle_cast({add, Person, Place}, State) ->
    NewState = maps:put(Person, Place, State),
    {noreply, NewState}.

handle_call({whereis, Person}, _From, State) ->
    Reply = case maps:find(Person, State) of
        {ok, Place} -> Place;
        error -> error
    end,
    NewState = State,
    {reply, Reply, NewState}.

handle_swap_code(State) ->
    {ok, State}.

尝试使用以下命令初始化服务器时:

MyServer = basic_gen_server:start(name_server).

我得到以下调试输出:

=ERROR REPORT==== 29-Oct-2014::12:41:42 ===
Error in process <0.70.0> with exit value: {undef,[{basic_gen_server,gen_server_loop,[name_server,#{}],[]}]}

从概念上讲,我理解将串行代码放入基本服务器系统的概念,但我相信我有一个语法错误,我无法使用语法突出显示或谷歌找到。在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

不导出函数gen_server_loop。因此,您无法致电basic_gen_server:gen_server_loop(Module, Module:init()),这就是spawn(basic_gen_server,gen_server_loop,[Module, Module:init()])内发生的事情。

如果您阅读了错误消息,它会告诉您要在undefined(trougn undef atom)中调用的函数。功能为{basic_gen_server,gen_server_loop,[name_server,#{}],[]},或您有{Module, Function, ListOfArgs, ...}的位置。你总是应该检查

  • 没有类型模块或功能名称
  • function arity匹配调用中的参数数量(错误消息中的列表)
  • 导出功能

如果未定义函数,则不会编译所有本地调用(如loop(SomeArgs),未指定模块)。您可以动态进行本地调用(FuntionName(SomeArgs),无需模块名称)。


在评论了本地电话的需要后,

编辑

你实际上可以使用lambda。有spawn/1个函数,如果你愿意,它需要lambda(或fun),所以你可以调用spawn( fun local_functino/0).。唯一的问题是你的fun不能接受任何参数,但是有一种解决方法,使用闭包。

spawn(fun () ->
         gen_server_loop(Module, Module:init())
      end).

gen_serve_loop保留本地电话。