Threading state in erlang

Chris Campbell cyberdanx@REDACTED
Wed Feb 15 18:48:08 CET 2006


Hi,

State is a pain, ain't it?  What's the best way to deal with this pest
in the following problem?

I'm trying to write some good stream handling stuff to make parsing
requests via TCP easier.  In the program we have SMod which provides
the basic stream operations for some type of stream.  This can be a
binary, tcp or anything that will support the interface.

For tcp I have to thread the state, since the stream works roughly as follows.

peek(#tcp_stream{socket=Socket, bytestream=Stream}=State,
          NumBytes) ->
  if
    size(Stream) >= NumBytes ->
      {Result, _Rest} = split(Stream, NumBytes),
      {ok, State, Result, NumBytes};
    true ->
      case tcp_gen:recv(Socket, 0) of
        {ok, Bin} ->
          NewSt=#tcp_stream{socket=Socket, list_to_binary([Stream, Bin])},
          peek(NewSt, NumBytes);
        {error, closed} ->
          {ok, State, Stream, size(Stream)}
      end
  end.

I've written some code that does matching on general streams,

match(SMod, Stream, Pattern) ->
  case SMod:peek_bytes(Stream, size(Pattern)) of
    {ok, NS, Pattern, size(Pattern)} ->
      {ok, T} = SMod:gobble_bytes(NS, size(Pattern)),
      {ok, T};
    {ok, NS, _X, _Y} ->
        {nomatch, NS};
    Other ->
      Other
  end.

The stream state is threaded through like this, sometimes unnecessarily.

case match(SMod, Stream, <<"SEARCH">>) of
  {ok, NS} ->
    parse_search_req(SMod, NS);
  {nomatch, NS} ->
    check_another(SMod, NS)...
end.

How can I avoid threading the state all over the place?


Cheers,
Chris Campbell



More information about the erlang-questions mailing list