[erlang-questions] %5Berlang-questions%5D%20Questions%20on%20gen_tcp%20%26%20flexible%20parsing%20-2-%0A%09%28readable&In-Reply-To=386001.61120.qm%40web51107.mail.re2.yahoo.co

Vlad Dumitrescu <>
Fri Apr 4 10:13:26 CEST 2008

I will try to address some of your questions.

First of all, the example is just an example, not everything is meant
to work in a real setting.

> server(LS) ->
>     case gen_tcp:accept(LS) of
>         {ok,S} ->
>             loop(S),
>         ?MODULE:start_servers(1,LS);
>     upgrade ->
>            io:format("TEST: ACPT upgrading ~p~n", [self()]),
>         ?MODULE:server(LS);
>         Other ->
>             io:format("accept returned ~w - goodbye!~n",[Other]),
>             ok
>     end,

gen_tcp:accept/1 doesn't return 'upgrade', so the case above won't
match. I think you are mixing return values with messages sent.

>     receive
>     upgrade ->
>            io:format("TEST: ACPT2 upgrading ~p~n", [self()]),
>         ?MODULE:server(LS);
>         Other1 ->
>             io:format("accept returned ~w - goodbye!~n",[Other1]),
>         server(LS)
>     end.

You might not receive any 'upgrade' message here either, because it is
consumed in loop/1, below.

> loop(S) ->
>     inet:setopts(S,[{active,once}]),
>     receive
>         {tcp,S,Data} ->
>             Answer = process(Data),
>             gen_tcp:send(S,Answer),
>             loop(S);
>         {tcp_closed,S} ->
>             io:format("Socket ~w closed [~w]~n",[S,self()]),
>             ok;
>     upgrade ->
>            io:format("TEST: Client upgrading ~p~n", [self()]),
>         ?MODULE:loop(S)
>     end.

I am sorry that I can't help you with more details, but I would
suggest that you understand first the workings of the example without
any upgrades. For trying out how code updating works, a simpler test
program could be useful, where it's easier to see what is happening.

In chapter 12.3 in the Kernel reference manual, it is explained how
code replacing works. You can only have two versions of a module
active. Loading for the third time kills all processes running version
1, so you have to give the system some time to switch to version 2. If
a process is blocked in a receive, it will still run version 1.

> *******************************************************************
> Parser questions:
> What does not work is this:
> parsecmd(Cmd, T) ->
>     parsecmd(Cmd, T, []).
> parsecmd(Cmd ++ T, L) ->
>     {Url, T1} = collect_usr(T, reverse("")),
>     parsecmd(T1, [Url|L]);
> .......
> One cannot insert a variable Cmd in this case to make this search more
> flexible, Erlang complains about it.  The statement to be evaluated MUST be
> a fixed one, which is not so nice, so "parsecmd(Cmd ++ T, L) ->" will not
> work,
> "parsecmd("{USR:" ++ T, L) ->" will, but the term is fixed, I would like it
> to be variable.

Yes, you can't have a variable there.
parsecmd("{USR:" ++ T, L) is a shortcut for parsecmd([${, $U, $S, $R,
$: | T], L).

Instead you could write a function
get_cmd(Str) -> {Cmd, T}
where Cmd is for example "{USR:"

and change parsecmd to parsecmd({Cmd, T}, L), calling it like
  parsecmd(T) ->
    parsecmd(get_cmd(T), []).

I hope this helps a little.


More information about the erlang-questions mailing list