Erlang nasce per la programmazione concorrente. E' disarmante la semplicità con cui creare un nuovo processo:
Pid = spawn(Mod, Func, Args).
in questo modo verrà allocato ed eseguito, in una virtual machine completa, un nuovo thread come
Mod:Func(Args).
Di fatto rappresenta un processo concorrente in esecuzione in un particolare node.
Utilizzando la funzione spawn è possibile in sostanza forkare ad esempio in un nuovo thread l'esecuzione di una funzione che, ad esempio, faccia polling su di una risorsa esterna:
Pid = spawn(fun() ->
%% fork execution
polling_fun()
end).
Questo semplice esempio in realtà è non banale, e mostra le potenzialità del linguaggio.
Il dannato IE colpisce ancora. Poichè il browser è particolarmente sensibile all'Header Content-Type di una risposta HTTP, ho dovuto modificare 'a manina' gli header delle risposta Http di un modulo proxy che sto sviluppando nel caro (!) Erlang.
Così ad esempio per adattare il Content-Type come 'text/xml' faccio:
% @doc Make a Http Response adjusting Headers
% @spec doHttpResponse(Code::list(), Header::list(),Body::string()) -> ok.
doHttpResponse(Code,Header,Body) ->
Data = list_to_binary(Body),
Headers1 =
case lists:keysearch("Content-Type", 1, Headers) of
{value, _} ->
[{"Content-Length", integer_to_list(size(Data))} | Headers];
_ ->
[{"Content-Type", "text/xml; charset=utf-8"},
{"Content-Length", integer_to_list(size(Data))} | Headers]
end,
{Code,Headers1,Body}.
dove Code, Header e Body sono il risultato del match alla GET Http:
{ok, {{Version, Code, ReasonPhrase}, Headers, Body}} =
http:request(get, { Path ++ URI ++ Qs , [] }, [], [])
--
LP
Lavorare con le stringhe in Erlang a volte può essere divertente:
Questa funzione in particolare cerca di fare un match di un token/espressione regolare in una lista di stringhe, e restituisce una lista delle stringhe che matchano l'espressione regolare o il token. La funzione considera anche possibili casi di eccezione:
%% @doc Match a string value in a list
%% @spec matchListValue(List::list(),Token::string()) -> list()
%% @author lp
matchListValue(List,Token) ->
lists:filter(fun(Elem) ->
case
catch
begin
case regexp:first_match(Elem,Token) of
nomatch ->
?INFO_MSG("regex does not match", []),
false;
{match, _, _} ->
?INFO_MSG("regex matches",[] ),
true
end
end of
true ->
?INFO_MSG("Matched",[]),
true;
false ->
?INFO_MSG("None",[]),
false;
{ 'EXIT', EX } ->
?INFO_MSG("Raised an exception",[ EX ] ),
false
end
end,List).
--
LP