Hatena::Grouperlang

檜山正幸のErlang未確認情報 RSSフィード

 | 

2009-01-17 (土)

helloをちゃんと作る (11) いくつかの注意

| 16:39

共通の定義はヘッダファイルにまとめる

サーバー名やスーパーバイザ名を定義するためには、-define を使うとよい。

-define(SERVER, hello_server).
-define(SUP, hello_sup).

だが、この定義を各ソースファイルに散りばめると、メンテナンスが困難。hello_names.hrlのようなヘッダーファイルに登録名の定義をまとめておくとよいだろう。

各種メッセージ、ロギング

今回のサンプルでは、io:fwrite, io:formatなどでメッセージ(出力)をイイカゲンに書いているが、実際には error_logger を使うべき。また、メッセージの種別(info, warning, error)や書式をよく考えて、一貫したスタイルにすべき。

ファイルの集約

次のファイル(モジュール)群を作った。

hello.erl アプリケーショントップレベルインターフェースモジュール
hello_api.erl 公開する関数を集めたインターフェースモジュール
hello_app.erl applicationコールバックモジュール
hello_server.erlgen_serverコールバックモジュール
hello_sup.erl トップスーパーバイザ
hello_impl.erl hello_serverの実装モジュール

App_implとApp_serverは1つにしてもよい。App_apiとAppも一緒にしてもかまわない。むしろ、一緒にしたほうが使いやすいこともある。App_api, App, App_appの3つを1つにまとめることもできる。

以下は、hello, hello_api, hello_appを1つにまとめた例。hello_api:stop/0とhello:stop/0 が名前の競合を起こすので、hello_api:stopをstop_server/0に改名している。便宜上、統合したモジュール名をhello_iifとしているが、実際はこれをhelloとすればいい。

%% -*- coding: utf-8 -*-

%% @doc helloアプリケーションの統合したインターフェースモジュール.
%% iif = Integrated InterFace
-module(hello_iif).

%% applicationコールバック
-behaviour(application).
-export([start/2, stop/1]).

%% アプリケーショントップレベルインターフェース
-export([ % 起動/停止
         start/0, stop/0
        ]).
-export([ % デバッグ/テストに便利
         modules/0, load/0, restart/0
        ]).

%% アプリケーションの外部インターフェース
-export([hello/0, hello/1, sleep/1, stop_server/0, crush/0]).

%% サーバー登録名
-define(SERVER, hello_server).
%% スーパーバイザ登録名
-define(APP, hello).


%% @spec (StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State} | {error, Reason}
%% where
%%   StartType = normal | {takeover,Node} | {failover,Node}
%%   Node = node()
%%   StartArgs = term()
%%   Pid = pid()
%%   State = term()
%% @doc helloアプリケーションのトップ・スーパーバイザを起動する.
start(_Type, _StartArgs) ->
  io:fwrite("hello_app:start(~p, ~p) : Starting the hello app.~n", 
            [_Type, _StartArgs]),
  hello_sup:start_link().

%% @spec stop(State::term()) -> ok
%% @doc helloアプリケーション終了後の処理(特になし).
stop(_State) ->
  io:fwrite("hello_app:stop(~p) : The hello app stopped.~n", 
            [_State]),
  ok.



%% @doc helloアプリケーションをスタートする.
%% @spec () -> ok | {error, Reason}
%% @end
%% application:start/2についてはマニュアルを参照のこと.
start() ->
  application:start(?APP).

%% @doc helloアプリケーションをストップする.
%% @spec () -> ok | {error, Reason}
stop() ->
  application:stop(?APP).

%%%%
%% 以下のコードはyaws.erlから拝借し、
%% 多少変更
%%%%

%% @doc helloアプリケーションを構成する全てのモジュール名のリストを返す.
%% @spec () -> [atom()]
modules() ->
  application:load(?APP),
  case application:get_key(?APP, modules) of
    {ok, List} -> 
      List;
    _ -> 
      []
  end.

%% @spec ([atom()]) -> ok
%% @end
%% lists:foreach/2 の戻り値は常にok
load(List) ->
  lists:foreach(fun c:l/1, List).

%% @doc helloアプリケーションを構成する全てのオブジェクトファイルをロードする.
%% @spec () -> ok
%% @end
%% lists:foreach/2 の戻り値は常にok
load() ->
  load(modules()).

%% @doc helloアプリケーションを再スタートする.
%% 新しいオブジェクトをロードしてからスタートするので、
%% 変更があればそれが反映される.
%% @spec () -> ok | {error, Reason}
restart() ->
  stop(),
  load(),
  start().

%% edocしてない、忘れた、いいとしよう.

%% @spec () -> ok
hello() ->
  gen_server:call(?SERVER, hello).
  
%% @spec (string()) -> ok
hello(Whom) ->
  gen_server:call(?SERVER, {hello, Whom}).

%% @spec (integer()) -> ok
sleep(MilliSec) ->
  gen_server:call(?SERVER, {sleep, MilliSec}).
  
%% @spec () -> none()
crush() ->
  gen_server:call(?SERVER, crush).

%% @spec () -> ok
stop_server() ->
  % gen_server:cast/2 はokを戻す.
  gen_server:cast(?SERVER, stop).

YasinYasin2012/02/09 04:00I was really confused, and this ansewred all my questions.

xwzliwxwzliw2012/02/09 22:07yIusIk <a href="http://nebrdzoytvby.com/">nebrdzoytvby</a>

jiqwbbdjiqwbbd2012/02/10 02:42c1SZR3 , [url=http://irzkzdxzanrf.com/]irzkzdxzanrf[/url], [link=http://abmxfrtvtshn.com/]abmxfrtvtshn[/link], http://crbtgcmkdrbt.com/

wvdslciwvdslci2012/02/10 04:05q8lSvf , [url=http://xxyhczqszsxi.com/]xxyhczqszsxi[/url], [link=http://piadszuzmedj.com/]piadszuzmedj[/link], http://fouwqfkmpjgv.com/

xjtzwxtfcnxjtzwxtfcn2012/02/10 07:00T4qB7J , [url=http://natfsecsnigp.com/]natfsecsnigp[/url], [link=http://qhfyzefntcms.com/]qhfyzefntcms[/link], http://netbopzeimlf.com/

luqvpmdluqvpmd2012/02/10 08:46btyauJ , [url=http://cllduaufqkkh.com/]cllduaufqkkh[/url], [link=http://cxlvnqjexnxl.com/]cxlvnqjexnxl[/link], http://vkzjnmmgwgyo.com/

jadeosnusjadeosnus2012/02/10 10:05T6lUoK , [url=http://hjgfbdqmxezk.com/]hjgfbdqmxezk[/url], [link=http://hdgzizuceygk.com/]hdgzizuceygk[/link], http://pnifsfvnqqjs.com/

mqtwymaslmqtwymasl2012/02/10 11:12b50w81 , [url=http://oaqslqioosyh.com/]oaqslqioosyh[/url], [link=http://nppsqmqvceee.com/]nppsqmqvceee[/link], http://jxehxrpfbdxk.com/

eflizfeflizf2012/02/11 20:55t4xBDn <a href="http://jekzuwqhksmt.com/">jekzuwqhksmt</a>

iycoarkzmliycoarkzml2012/02/13 04:22hgNGDV , [url=http://kdvqurhjtgxs.com/]kdvqurhjtgxs[/url], [link=http://rgzfwswoiktj.com/]rgzfwswoiktj[/link], http://kkwqepmwmhvx.com/

 |