この回答には2つの部分があります。第一に、Erlangにかなり熟練するまで、paramatizedモジュールを使用したくないということです。彼らがあなたに与えるのは、引数を渡す別の方法です。
-module(test_module, [Param1]).
some_method() -> Param1.
は、前者が全くずっとあなたを購入していません
-module(test_non_paramatized_module).
some_method(Param1) -> Param1.
と同等であり、非常に少ない既存のErlangのコードは、そのスタイルを使用しています。
start_link関数にname引数(異なる名前で登録された同じgen_serverをいくつも作成していると仮定します)を渡す方が通常です。
start_link(Name) -> gen_server:start_link({local, Name}, ?MODULE, [Name], []).
回答への第2の部分は、gen_serverはparamatizedモジュールと互換性があることである。
-module(some_module, [Param1, Param2]).
start_link() ->
PModule = ?MODULE:new(Param1, Param2),
gen_server:start_link(PModule, [], []).
Param1
とParam2
は、すべてのgen_serverコールバック関数で利用できるようになります。
start_link
がparamatizedモジュールに属しているようゼッドは、言及として、あなたはそれを呼び出すために、次の手順を実行する必要があります:
Instance = some_module:new(Param1, Param2),
Instance:start_link().
私は、これは特に醜いスタイルであることがわかりました - 呼び出すコードsome_module:new/n
は、モジュールパラメータの数と順序を知っていなければなりません。 some_module:new/n
を呼び出すコードもsome_module
には存在しません。これにより、モジュールのパラメータの数や順序が変更されると、ホットアップグレードがより困難になります。 some_module
コードをアップグレードする方法が見つかったとしても、2つのモジュール(some_module
とそのインターフェイス/コンストラクタモジュール)の代わりに2つのモジュールのロードを調整する必要があります。マイナーノートでは、このスタイルにより、some_module:start_link
用のコードベースをgrepするのがやや難しくなります。
gen_servers
にパラメータを渡すために推奨される方法は、gen_server:start_link/3,4
関数の引数を経由して、明示的であり、あなたが?MODULE:init/1
callackから復帰状態値に格納します。このスタイルを使用して
-module(good_style).
-record(state, {param1, param2}).
start_link(Param1, Param2) ->
gen_server:start_link(?MODULE, [Param1, Param2], []).
init([Param1, Param2]) ->
{ok, #state{param1=Param1,param2=Param2}}.
は、あなたがまだ完全にparamatizedモジュール(新しい、まだ実験的な機能)をサポートしていないOTPのさまざまな部分でキャッチされないことを意味します。また、gen_serverインスタンスの実行中に状態値を変更できますが、モジュールパラメータでは変更できません。
このスタイルでは、コード変更メカニズムによるホットアップグレードもサポートしています。 code_change/3
関数が呼び出されると、新しい状態値を返すことができます。新しいparamatizedモジュールインスタンスをgen_server
コードに返す対応する方法はありません。
それぞれ異なる名前の同じコールバックモジュールを使用して、複数のgen_serversを作成しますか?同じ名前の複数のgen_servers? – Jacob
同じコールバックモジュールを使用する複数のgen_servers。 start_linkに名前を渡して、別の「インスタンス」を登録することができます。 1つのインスタンスがある場合は、モジュールと同じ名前を付けるのが一般的で、公開APIは次のように動作します。 some_module:some_function() ...これは単なる利便性のようです。 gen_serverを別の名前で登録すると、それはもう動作しません。 私は次のようなものにしたいと思います。 1> Mod:some_function()。 2> Mod1:some_function()。 ...各変数はgen_serverモジュールの異なるインスタンスを参照します – mwt
あるいは、なぜこれに気を付けるべきではないかを知りたいと思います。私が見たすべてのgen_serverイントロでは、単にgen_serverキャスト/コールを使用するのではなく、APIを設定しています。Erlangの新機能であるので、私は簡単に多くのプロセスをクローンできると思っていましたが、gen_serversの名前を変更するとすぐにAPI機能が停止するのは驚きです。 – mwt