2010-07-17 18 views
6

Cuando aprendo Erlang, intento resolverlo. 4.1 ("Un servidor Echo") del libro "Erlang Programming" (de O'Reilly) y tengo un problema. Mi código es el que:Problema de servidor simple de Erlang

-module(echo). 
-export([start/0, print/1, stop/0, loop/0]). 

start() -> 
    register(echo, spawn(?MODULE, loop, [])), 
    io:format("Server is ready.~n"). 

loop() -> 
    receive 
     {print, Msg} -> 
      io:format("You sent a message: ~w.~n", [Msg]), 
      start(); 
     stop -> 
      io:format("Server is off.~n"); 
     _ -> 
      io:format("Unidentified command.~n"), 
      loop() 
    end. 

print(Msg) -> ?MODULE ! {print, Msg}. 

stop() -> ?MODULE ! stop. 

Desafortunadamente, tengo algunos problemas. Al encender funciona como se esperaba, genera un nuevo proceso y muestra el mensaje "El servidor está listo". Pero cuando trato de usar la función de impresión (como echo:print("Some message.")., por ejemplo) obtuve el resultado, pero no funciona como me gustaría. Imprime mi mensaje como una lista (no como una cadena) y genera

=ERROR REPORT==== 18-Jul-2010::01:06:27 === 
Error in process <0.89.0> with exit value: {badarg,[{erlang,register,[echo,<0.93.0>]},{echo,start,0}]} 

mensaje de error. Por otra parte, cuando trato de dejar de servidor en los echo:stop() Tengo otro error

** exception error: bad argument 
in function echo:stop/0 

me podría explicar a nadie, lo que está pasando aquí? Soy nuevo en Erlang y parece ser bastante difícil de entender para mí en este momento.

+0

Las cadenas se representan como listas en erlang. – Jonas

+0

Por supuesto, tiene razón, pero dado que no hay caracteres, que no se pudieron mostrar, ¿por qué se muestra como una lista, no como una cadena? Pero esto es solo una cosa, no la más importante, el problema sigue siendo el mismo. – Zbigniew

+0

@Hynek ha explicado el problema principal. Las cadenas son listas de enteros, por lo que '" abc "' es lo mismo que '[97,98,99]'. Entonces erlang realmente no "sabe" si su lista de enteros es solo una lista de enteros o una cadena. Usando '~ w' en una cadena de formato solo se imprime como una lista. Si usa '~ p'it probará si las listas de enteros pueden ser cadenas imprimibles y si es así imprímalas como cadenas. Esto es lo que hace el caparazón. Sí, esto fue intencionado, no, no es un error. Tener cadenas como listas hace que sea muy fácil trabajar con ellas. – rvirding

Respuesta

9

Cuando su función loop/0 recibir print mensaje que llame de nuevo start/0 cual genera nuevo proceso y tratar de registrarlo como echo nuevo. Causa que su servidor fallezca y el nuevo no esté registrado como echo, por lo que ya no puede enviar un mensaje por la función print/1.

loop() -> 
    receive 
     {print, Msg} -> 
      io:format("You sent a message: ~w.~n", [Msg]), 
      loop(); % <-- just here! 
     stop -> 
      io:format("Server is off.~n"); 
     _ -> 
      io:format("Unidentified command.~n"), 
      loop() 
    end. 
+0

Por supuesto, fue así de simple. Muchas gracias, parece que estaba cansado y no noté un error obvio. Gracias de nuevo. – Zbigniew