読者です 読者をやめる 読者になる 読者になる

dictのサーバ化

Erlang

gen_serverを使ってdictをサーバ化しようと思ったけど、ここまで書いてよくわからないエラーがでた。

%% File: dict_server.erl
%% dictをgen_serverを使ってサーバー化する(ただのwrapper)
%% Tsungのソースを参考にした。
%%
%% ToDo:
%% * エラーハンドリングどうしよう
%%
%%
-module(dict_server).
-behabiour(gen_server).

%% External exports
-export([start/0, stop/0]).
-export([append/2, append_list/2, erase/1, fetch/1, fetch_keys/0,
         filter/1, find/1, fold/2, is_key/1, map/1, store/2, to_list/0,
         update/2, update/3, update_counter/2]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
         code_change/3]).

%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------

%% server function
start() ->
    gen_server:start({global, ?MODULE}, ?MODULE, [],[]).
stop() ->
    gen_server:call({global, ?MODULE}, {stop}).

%% wrappers
append(Key, Value) ->
    gen_server:call({global, ?MODULE}, {append, Key, Value}).
appned_list(Key, ValList) ->
    gen_server:call({global, ?MODULE}, {append_list, Key, ValList}).
erase(Key) ->
    gen_server:call({global, ?MODULE}, {erase, Key}).
fetch(Key) ->
    gen_server:call({global, ?MODULE}, {fetch, Key}).
fetch_keys() ->
    gen_server:call({global, ?MODULE}, {fetch_keys}).
filter(Pred) ->
    gen_server:call({global, ?MODULE}, {filter, Pred}).
find(Key) ->
    gen_server:call({global, ?MODULE}, {find, Key}).
fold(Fun, Acc0) ->
    gen_server:call({global, ?MODULE}, {fold, Fun, Acc0}).
%from_list(List)
is_key(Key) ->
    gen_server:call({global, ?MODULE}, {is_key, Key}).
map(Fun) ->
    gen_server:call({global, ?MODULE}, {map, Fun}).
%merge(Fun,)
store(Key, Value) ->
    gen_server:call({global, ?MODULE}, {store, Key, Value}).
to_list() ->
    gen_server:call({global, ?MODULE}, {to_list}).
update(Key, Fun) ->
    gen_server:call({global, ?MODULE}, {update, Key, Fun}).
update(Key, Fun, Initial) ->
    gen_server:call({global, ?MODULE}, {update, Key, Fun, Initial}).
update_counter(Key, Increment) ->
    gen_server:call({global, ?MODULE}, {update_counter, Key, Increment}).

%%%----------------------------------------------------------------------
%%% Callback functions from gen_server
%%%----------------------------------------------------------------------

%%----------------------------------------------------------------------
%% Func: init/1
%% Returns: {ok, State}          |
%%          {ok, State, Timeout} |
%%          ignore               |
%%          {stop, Reason}
%%----------------------------------------------------------------------
init([]) ->
    {ok, dict:new()}.

%%----------------------------------------------------------------------
%% Func: handle_call/3
%% Returns: {reply, Reply, State}          |
%%          {reply, Reply, State, Timeout} |
%%          {noreply, State}               |
%%          {noreply, State, Timeout}      |
%%          {stop, Reason, Reply, State}   | (terminate/2 is called)
%%          {stop, Reason, State}            (terminate/2 is called)
%%----------------------------------------------------------------------
handle_call({append, Key, Value}, _From, State) ->
    {reply, ok, dict:append(Key,Value, State)};
handle_call({append_list, Key,ValList}, _From, State) ->
    {reply, ok, dict:append_list(Key, ValList, State)};
handle_call({erase, Key}, _From, State) ->
    {reply, ok, dict:erase(Key, State)};
handle_call({fetch, Key}, _From, State) ->
    {reply, dict:fetch(Key, State),State};
handle_call({fetch_keys}, _From, State) ->
    {reply, dict:fetch_keys(State), State};
handle_call({filter, Pred}, _From, State) ->
    {reply, ok, dict:filter(Pred, State)};
handle_call({find, Key}, _From, State) ->
    {reply, dict:find(Key, State), State};
handle_call({fold, Fun, Acc0}, _From, State) ->
    {reply, dict:fold(Fun, Acc0, State), State};
handle_call({is_key, Key}, _From, State) ->
    {reply, dict:is_key(Key, State)};
handle_call({map, Fun}, _From, State) ->
    {reply, ok, dict:map(Fun, State)};
handle_call({store, Key, Value}, _From, State) ->
    {reply, ok, dict:store(Key, Value, State)};
handle_call({to_list}, _From, State) ->
    {reply, dict:to_list(State), State};
handle_call({update, Key, Fun}, _From, State) ->
    {reply, ok, dict:update(Key, Fun, State)};
handle_call({update, Key, Fun, Initial}, _From, State) ->
    {reply, ok, dict:update(Key, Fun, Initial, State)};
handle_call({update_counter, Key, Increment}, _From, State) ->
    {reply, ok, dict:update_counter(Key, Increment, State)};
handle_call({stop}, _From, State) ->
    {stop, nomal, State}.

%%----------------------------------------------------------------------
%% Func: handle_cast/2
%% Returns: {noreply, State}               |
%%          {noreply, State, Timeout}      |
%%          {stop, Reason, State}            (terminate/2 is called)
%%----------------------------------------------------------------------
handle_cast(_Request, State) ->
    {noreply, State}.

%%----------------------------------------------------------------------
%% Func: handle_info/2
%% Returns: {noreply, State}               |
%%          {noreply, State, Timeout}      |
%%          {stop, Reason, State}            (terminate/2 is called)
%%----------------------------------------------------------------------
handle_info(_Info, State) ->
    {noreply, State}.

%%----------------------------------------------------------------------
%% Func: terminate/2
%% Purpose: Shutdown the server
%% Returns: any (ignore by gen_server)
%%----------------------------------------------------------------------
terminate(_Reason, _State) ->
    ok.

%%----------------------------------------------------------------------
%% Func: code_change/3
%% Purpose: Convert process state when code is changed
%% Returns: {ok, NewState, NewStateData}
%%----------------------------------------------------------------------
code_change(_OldVsn, StateData, _Extra) ->
    {ok, StateData}.

%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------
ubuntu-desktop% erlc dict_server.erl
erlc dict_server.erl
./dict_server.erl:14: function append_list/2 undefined
./dict_server.erl:35: Warning: function appned_list/2 is unused
ubuntu-desktop%

append_listは定義されているはずなのに。。。なんでだ?

返り値違いで

is_keyで落ちる。。つか、現状dictで例外が発生したら何でも撃沈。こーゆー場合、Replyにエラーを入れて、返り値みてエラーをthrowしなおすのがよいのかな?これならgen_server:callをラップすればよいし。

あ゛ーーーーーーーーーー!!

append_listがappned_listになってるorz