How do you parameterize the gen_server module?

EDIT:

I do not want to use parameters as a universal way to create Erlang programs - I am still studying traditional design principles. I also do not want to imitate OOP. My only concern here is to make my gen_server calls consistent between server instances. This is more like fixing a broken abstraction for me. I can imagine a world in which a language or OTP made it convenient to use any instance of gen_server api, and that the world I want to live in.

Thanks to Zed for showing that my main goal is possible.


Can someone figure out a way to use parameterized modules in gen_servers? In the following example, suppose test_child is gen_server with one parameter. When I try to run it, all I get is:

42> {test_child, "hello"}:start_link().
** exception exit: undef
     in function  test_child:init/1
        called as test_child:init([])
     in call from gen_server:init_it/6
     in call from proc_lib:init_p_do_apply/3

Ultimately, I'm trying to figure out a way to use multiple named instances of gen_server. As far as I can tell, once you start doing this, you can no longer use your pretty API and throw messages in your instances using gen_server: call and gen_server: cast. If I could give the instances my names, this problem could be alleviated.

+5
source share
4 answers

. -, , , , Erlang. , , .

-module(test_module, [Param1]).

some_method() -> Param1.

-module(test_non_paramatized_module).

some_method(Param1) -> Param1.

, Erlang .

name ( , gen_servers, ) start_link.

start_link(Name) -> gen_server:start_link({local, Name}, ?MODULE, [Name], []).

, gen_server :

-module(some_module, [Param1, Param2]).

start_link() -> 
  PModule = ?MODULE:new(Param1, Param2),
  gen_server:start_link(PModule, [], []).

Param1 Param2 gen_server.

Zed, start_link , :

Instance = some_module:new(Param1, Param2),
Instance:start_link().

, - , some_module:new/n, . , some_module:new/n, some_module . , , , . (some_module /), some_module. grep some_module:start_link.


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}}.

, OTP, ( ). , gen_server, .

. code_change/3, . gen_server.

+10

:

  • archaelus . , , , - , .

  • , , , , ! , , , .

+10

, . , OO- gen_servers. - , The Bad Thing. register BIF - - (, , - ).

+3
source
-module(zed, [Name]).
-behavior(gen_server).

-export([start_link/0, init/1, handle_cast/2]).
-export([increment/0]).

increment() ->
    gen_server:cast(Name, increment).

start_link() ->
    gen_server:start_link({local, Name}, {?MODULE, Name}, [], []).

init([]) ->
    {ok, 0}.

handle_cast(increment, Counter) ->
    NewCounter = Counter + 1,
    io:format("~p~n", [NewCounter]),
    {noreply, NewCounter}.

This module works fine for me:

Eshell V5.7.2  (abort with ^G)
1> S1 = zed:new(s1).
{zed,s1}
2> S1:start_link().
{ok,<0.36.0>}
3> S1:increment().
1
ok
4> S1:increment().
2
ok
-4
source

All Articles