我在OS X 10.9.2上运行Erlang R16B03-1 (erts-5.10.4)
。 Erlang是使用brew安装的。
我正在尝试运行gen_server模块。
-module(logger).
-author("evangelosp").
-behaviour(gen_server).
%% API
-export([start/0, stop/0, log/2]).
%% gen_server callbacks
-export([init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
terminate/2,
code_change/3]).
-define(SERVER, ?MODULE).
%%%===================================================================
%%% API
%%%===================================================================
start() -> gen_server:start_link({global, ?SERVER}, ?MODULE, [], []).
stop() -> gen_server:call(?MODULE, stop).
log(_Level, _MSG) -> gen_server:call(?MODULE, {add, {_Level, _MSG}}).
%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
init([]) -> {ok, ets:new(?MODULE, [])}.
handle_call(_Request, _From, Table) -> {reply, {ok, ["Mplah!", _Request, _From, Table]}, Table}.
handle_cast(_Request, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
在我正在运行的erlang shell中:
Eshell V5.10.4 (abort with ^G)
1> c(logger).
{ok,logger}
2> logger:start().
{ok,<0.40.0>}
3> logger:log(info, "Hello World").
** exception exit: {noproc,{gen_server,call,
[logger,{add,{info,"Hello World"}}]}}
in function gen_server:call/2 (gen_server.erl, line 180)
我无法摆脱那个例外。我实际上没有通过查找异常消息找到任何有用的资源,但this没有多大帮助。
干杯。
答案 0 :(得分:2)
在代码start() -> gen_server:start_link({global, ?SERVER}, ?MODULE, [], []).
中,您使用{global, ?SERVER}
,这意味着:
如果ServerName = {global,GlobalName},则注册gen_server 使用global:register_name / 2全局作为GlobalName。
因此,当您向服务器发送消息时,您应该写log(_Level, _MSG) -> gen_server:call({global, ?MODULE}, {add, {_Level, _MSG}}).
。请参阅erlang doc:
呼叫(ServerRef,请求,超时) - &gt;答复 类型: ServerRef =名称| {Name,Node} | {global,GlobalName} | ServerRef可以是:
名称,如果gen_server是本地注册的,
{global,GlobalName},如果gen_server是全局注册的。
答案 1 :(得分:1)
您的服务器未注册,因此只能通过其pid访问。但是接口函数使用隐式宏?MODULE(在编译时由logger替换)来访问它。
您需要更改界面功能,或者在启动功能中注册服务器:
start() ->
{ok,Pid} = gen_server:start_link({global, ?SERVER}, ?MODULE, [], []),
register(?MODULE,Pid).
[编辑]感谢Evalon,我在答案中做了更正:o)