Desenvolva um conjunto de funções em Erlang, que modelize as actividades habituais duma biblioteca
segundo o modelo cliente-servidor.
-module(aula8).
-export([start/0, biblioteca/0, introduzir/1, retirar/1, emprestar/1, devolver/1, listar/0]).
-define(BIBLIOTECA_NO, andy@jardel).
start() -> spawn( ?MODULE, biblioteca, [] ).
biblioteca() ->
register( biblioteca, self() ),
bib_processo( { [], 1 } ),
io:format("serviço biblioteca terminou!").
bib_processo( {Livros, Num} ) ->
receive
{ msg_introduzir, Pid, Titulo } ->
LivrosNovo_tuplo = introduzir( Titulo, { Livros, Num } ),
Pid ! { msg_introduzir_conf, Num },
bib_processo( LivrosNovo_tuplo );
{ msg_retirar, Pid, NumExcluir } ->
case apagar( NumExcluir, Livros ) of
erro ->
Pid ! { msg_retirar_erro, NumExcluir },
bib_processo( { Livros, Num } );
LivrosActual ->
Pid ! { msg_retirar_conf, NumExcluir },
bib_processo( { LivrosActual, Num } )
end;
{ msg_emprestar, Pid, NumEmprestar } ->
case emprestar( NumEmprestar, Livros ) of
erro ->
Pid ! { msg_emprestar_erro, NumEmprestar },
bib_processo( { Livros, Num } );
LivrosActual ->
Pid ! { msg_emprestar_conf, NumEmprestar },
bib_processo( { LivrosActual, Num } )
end;
{ msg_devolver, Pid, NumDevolver } ->
case devolver( NumDevolver, Livros ) of
erro ->
Pid ! { msg_devolver_erro, NumDevolver },
bib_processo( { Livros, Num } );
LivrosActual ->
Pid ! { msg_devolver_conf, NumDevolver },
bib_processo( { LivrosActual, Num } )
end;
{ msg_listar, Pid } ->
Pid ! { msg_listar_conf, Livros },
bib_processo( {Livros, Num} )
end.
introduzir( Titulo, { Lista, Num } ) ->
{ [ { Num, Titulo, disponivel } | Lista ], Num + 1 }.
apagar( Num, Livros ) ->
case [ X || X <- Livros, element( 1, X ) == Num ] of
[] ->
erro;
[ Livro ] ->
[ X || X <- Livros, element(1, X) =/= Num ];
_ ->
erro
end.
emprestar( Num, Livros ) ->
case [ X || X <- Livros, element(1, X) == Num, element(3, X) == disponivel ] of
[] ->
erro;
[ { Num, Titulo, disponivel } ] ->
[ { Num, Titulo, emprestado } | [ X || X <- Livros, element(1, X) =/= Num ] ];
_ ->
erro
end.
devolver( Num, Livros ) ->
case [ X || X <- Livros, element(1, X) == Num, element(3, X) == emprestado ] of
[] ->
erro;
[{ Num, Titulo, emprestado }] ->
[ { Num, Titulo, disponivel } | [ X || X <- Livros, element(1, X) =/= Num ] ];
_ ->
erro
end.
% interface
introduzir( Titulo ) ->
{ biblioteca, ?BIBLIOTECA_NO } ! { msg_introduzir, self(), Titulo },
receive
{ msg_introduzir_conf, Num } ->
io:format( "Livro ~w, introduzido na BD com o numero ~w.~n", [ Titulo, Num ] )
end.
retirar( Num ) ->
{ biblioteca, ?BIBLIOTECA_NO } ! { msg_retirar, self(), Num },
receive
{ msg_retirar_conf, Num } ->
io:format( "Livro ~w, retirado da BD.~n", [ Num ] );
{ msg_retirar_erro, Num } ->
io:format( "Livro ~w NAO existe da BD.~n", [ Num ] )
end.
emprestar( Num ) ->
{ biblioteca, ?BIBLIOTECA_NO } ! { msg_emprestar, self(), Num },
receive
{ msg_emprestar_conf, Num } ->
io:format( "Livro ~w emprestado.~n", [ Num ] );
{ msg_emprestar_erro, Num } ->
io:format( "Livro ~w, NAO esta disponivel.~n", [ Num ] )
end.
devolver( Num ) ->
{ biblioteca, ?BIBLIOTECA_NO } ! { msg_devolver, self(), Num },
receive
{ msg_devolver_conf, Num } ->
io:format( "Livro ~w devolvido.~n", [ Num ] );
{ msg_devolver_erro, Num } ->
io:format( "Livro ~w, NAO esta emprestado.~n", [ Num ] )
end.
listar( ) ->
{ biblioteca, ?BIBLIOTECA_NO } ! { msg_listar, self() },
receive
{ msg_listar_conf, ListaLivros } ->
io:format( "Livros e seus estados:~n", [] ),
apresentalivros( ListaLivros )
end.
apresentalivros( [] ) -> true;
apresentalivros( [ { Num, Titulo, Estado } | Livros ] ) ->
io:format("Numero: ~w Titulo: ~w Estado: ~w~n", [ Num, Titulo, Estado ]),
apresentalivros( Livros ).

Última actualização: 14 Março 2000