Skip to content

Instantly share code, notes, and snippets.

@d11wtq
Created March 23, 2013 11:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save d11wtq/5227421 to your computer and use it in GitHub Desktop.
Save d11wtq/5227421 to your computer and use it in GitHub Desktop.
%% @doc This implements a kitchen fridge that you can put things into
%% and take them out.
%%
%% It is stateful, through the use of recursion.
%% I opted for the sets module only because I wanted to try it.
%% Using the sets module has the side-effect that you can only store
%% one of each food item in the fridge.
-module(kitchen).
-export([new/0, store/2, take/2]).
%% @doc Create a new Fridge to store Food items.
%% The Fridge runs in a separate process.
%%
%% @spec new() -> Fridge
new() ->
{fridge, spawn_link(fun() -> accept(sets:new()) end)}.
%% @doc Put something in the Fridge.
%% If the item is already in the Fridge, does nothing.
%%
%% @spec store(Food, Fridge) -> ok.
store(Food, {fridge, Pid}) ->
Pid ! {self(), {store, Food}},
receive
{Pid, Reply} -> Reply
end.
%% @doc Take something back out of the fridge.
%% If the item is not in the fridge, returns not_found.
%%
%% @spec take(Food, Fridge) -> {ok, Food} | not_found.
take(Food, {fridge, Pid}) ->
Pid ! {self(), {take, Food}}, ok,
receive
{Pid, Reply} -> Reply
end.
%% @private
accept(Contents) ->
receive
{From, {store, Food}} ->
From ! {self(), ok},
accept(sets:add_element(Food, Contents));
{From, {take, Food}} ->
case sets:is_element(Food, Contents) of
true -> From ! {self(), {ok, Food}};
false -> From ! {self(), not_found}
end,
accept(sets:del_element(Food, Contents));
{_, quit} -> quit
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment