Events 如何在Erlang中使用gen_事件调用?

Events 如何在Erlang中使用gen_事件调用?,events,erlang,otp,fsm,Events,Erlang,Otp,Fsm,我正在使用gen\u事件行为,当我试图发出gen\u事件:call时,我得到以下错误: > =CRASH REPORT==== 22-Dec-2019::19:17:43.030000 === crasher: > initial call: gen_event:init_it/6 > pid: <0.215.0> > registered_name: hev > exception exit: {undef,[{fm

我正在使用
gen\u事件
行为,当我试图发出
gen\u事件:call
时,我得到以下错误:

> =CRASH REPORT==== 22-Dec-2019::19:17:43.030000 ===   crasher:
>     initial call: gen_event:init_it/6
>     pid: <0.215.0>
>     registered_name: hev
>     exception exit: {undef,[{fm,state,[<0.215.0>],[]},
>                             {erl_eval,do_apply,6,
>                                       [{file,"erl_eval.erl"},{line,684}]},
>                             {shell,exprs,7,[{file,"shell.erl"},{line,686}]},
>                             {shell,eval_exprs,7,
>                                    [{file,"shell.erl"},{line,642}]},
>                             {shell,eval_loop,3,
>                                    [{file,"shell.erl"},{line,627}]}]}
>       in function  gen_event:terminate_server/4 (gen_event.erl, line 354)
>     ancestors: [<0.212.0>]
>     message_queue_len: 1
>     messages: [{'EXIT',<0.212.0>,normal}]
>     links: []
>     dictionary: []
>     trap_exit: true
>     status: running
>     heap_size: 610
>     stack_size: 27
>     reductions: 279   neighbours:
处理程序

handle_event({append,Elem},State=#state{xs=XS})->
    {ok,#state{xs=[Elem|XS]}};

handle_call(state,State})->     
    {ok,State,State};
handle_call(Event,State)->
    {ok,nada_for_you,State}.
p.S我没有发布所有需要的方法(代码更改、终止..等),但它们是存在的

我没有发布所有需要的方法(代码更改、终止..等),但它们是存在的

1) 无论如何,它们是可选的。检查文档中的绿色大注释,例如

2) 至于你的错误信息:

4) 这里有一个基本语法错误:

 handle_call(state,State})-> 
5) 您正在使用错误数量的参数调用两个函数

您需要更加勤奋地发布实际会产生错误的代码

下面是一个使用
gen_event
创建计数器的简单示例:

-module(counter).
-behaviour(gen_event).
-compile(export_all).

%% Callback functions:

init(StartingCount) ->  % Called by gen_event:add_handler()
    State = StartingCount,
    {ok, State}.

terminate(_Reason, State) ->
    io:format("Terminating state was: ~w~n", [State]).

% Calls to gen_event:notify() cause this function to execute:
handle_event({increase, Change}, State) -> 
    NewState = State+Change,
    {ok, NewState};
handle_event({decrease, Change}, State) ->
    NewState = State-Change,
    {ok, NewState}.

% Calls to gen_event:call() cause this function to execute:
handle_call(get_count, State) ->  
    Reply = io_lib:format("Reply from handle_call(): count is ~w~n", [State]),
    {ok, Reply, State};
handle_call({increase_and_get_count, Change}, State) ->
    NewState = State+Change,
    Reply = io_lib:format("Reply from handle_call(): count is ~w~n", [NewState]),
    {ok, Reply, NewState}.


%% User interface functions:

start(StartingCount) ->
    ServerName = gen_event_counter,
    CallbackModule = counter,

    {ok, _Pid} = gen_event:start_link({local, ServerName}),  
    %Name of process running gen_event server is: gen_event_counter

    ok = gen_event:add_handler(ServerName, CallbackModule, StartingCount). 
    %StartingCount is passed to init() callback


stop() ->
    ok = gen_event:stop(gen_event_counter),
    stopped.

send_request_with_notify(Request) -> 
    gen_event:notify(gen_event_counter, Request). % returns immediately, does not wait for a reply.
    % Request = {increase, 1}, {decrease, 2}, etc. 
    % Request is passed as first arg to handle_event().


send_request_with_call(Request) -> 
    Reply = gen_event:call(gen_event_counter, counter, Request), % waits for a reply  
    % Request is passed as first arg to handle_call()
    io:format("send_request_with_call() returned => ~s", [Reply]).
在外壳中:

~/erlang_programs/gen_event$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)

1> c(counter).                                                 
counter.erl:3: Warning: export_all flag enabled - all functions will be exported
{ok,counter}

2> counter:start(0).                                           
ok

3> counter:send_request_with_call(get_count).                  
send_request_with_call() returned => Reply from handle_call(): count is 0
ok

4> counter:send_request_with_notify({increase, 2}).            
ok

5> counter:send_request_with_call(get_count).      
send_request_with_call() returned => Reply from handle_call(): count is 2
ok

6> counter:send_request_with_call({increase_and_get_count, 5}).
send_request_with_call() returned => Reply from handle_call(): count is 7
ok

7> counter:stop().                                             
Terminating state was: 7
stopped

8> 
~/erlang_programs/gen_event$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)

1> c(hev).         
hev.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,hev}

2> hev:start().    
ok

3> hev:get_state().
{state,[1]}

4> hev:append(45). 
ok
hev:handle_event() called

5> hev:get_state().
{state,[45,1]}

6> hev:other_calls().
nada_for_you

7> hev:stop().
stopped

8> 
修复代码中的所有错误后:

-module(hev).
-compile(export_all).
-behaviour(gen_event).

-record(state,{
    xs=[]
}).

%callbacks
init(no_args)->
    {ok, #state{xs=[1]} }.

handle_event({append,Elem}, #state{xs=XS} ) ->
    io:format("hev:handle_event() called~n"),
    {ok, #state{xs=[Elem|XS]}}.

handle_call(get_state, State)->     
    Reply = State,
    {ok, Reply, State};
handle_call(_Other, State)->
    Reply = nada_for_you,
    {ok, Reply, State}.

%**API**

start()->
    gen_event:start_link({local, ?MODULE}),  %Sets the gen_event server name to ?MODULE

    %                     Server   Callback  Args for
    %                     Name     module    init()
    gen_event:add_handler(?MODULE, ?MODULE, no_args). 
    %Tells the gen_event server named ?MODULE to look for the callback functions 
    %in a module also named ?MODULE

append(Elem)->
    %                Server    Request
    %                Name      (matches against 1st arg in handle_event() )
    gen_event:notify(?MODULE, {append, Elem}).

get_state()->
    %              Server   Calback  Request
    %              Name     module   (matches against 1st arg in handle_call() )
    gen_event:call(?MODULE, ?MODULE, get_state).

other_calls() ->
    gen_event:call(?MODULE, ?MODULE, {set_state, [1, 2, 3]}).


stop() ->
    ok = gen_event:stop(?MODULE),
    stopped.
在外壳中:

~/erlang_programs/gen_event$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)

1> c(counter).                                                 
counter.erl:3: Warning: export_all flag enabled - all functions will be exported
{ok,counter}

2> counter:start(0).                                           
ok

3> counter:send_request_with_call(get_count).                  
send_request_with_call() returned => Reply from handle_call(): count is 0
ok

4> counter:send_request_with_notify({increase, 2}).            
ok

5> counter:send_request_with_call(get_count).      
send_request_with_call() returned => Reply from handle_call(): count is 2
ok

6> counter:send_request_with_call({increase_and_get_count, 5}).
send_request_with_call() returned => Reply from handle_call(): count is 7
ok

7> counter:stop().                                             
Terminating state was: 7
stopped

8> 
~/erlang_programs/gen_event$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)

1> c(hev).         
hev.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,hev}

2> hev:start().    
ok

3> hev:get_state().
{state,[1]}

4> hev:append(45). 
ok
hev:handle_event() called

5> hev:get_state().
{state,[45,1]}

6> hev:other_calls().
nada_for_you

7> hev:stop().
stopped

8> 

请注意,
notify()
会导致使用
add\u handler()
添加的所有模块中的
handle\u event()
函数执行,而
call()
针对特定模块的
handle\u call()
函数。

乍一看,问题在于
gen\u event:call(Pid,state)
。没有导出
genu事件:call/2
函数,只有,这意味着您必须显式地将处理程序传递给
genu事件:call
。另外请注意,
genu event:notify/2
将返回
:ok
,无论发生什么情况,这并不意味着呼叫成功。
~/erlang_programs/gen_event$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)

1> c(hev).         
hev.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,hev}

2> hev:start().    
ok

3> hev:get_state().
{state,[1]}

4> hev:append(45). 
ok
hev:handle_event() called

5> hev:get_state().
{state,[45,1]}

6> hev:other_calls().
nada_for_you

7> hev:stop().
stopped

8>