Polymorphic record question

Christian S chsu79@REDACTED
Mon Jun 19 10:59:11 CEST 2006


How about an accessor function:

sequenceNumber(#p2psyn{sequenceNumber=Seq}) ->
  Seq;
  ...
sequenceNumber(#p2pfin{sequenceNumber=Seq}) ->
  Seq.

Or is the different kinds of packets not restricted, instead new ones will be
defined later on by dynamicly loaded code?

If the latter is the case then you should probably store which
position of the record that hold the sequence number, and then use
erlang:element/2 to fetch the value at that position in the tuple
(since records are implemented on top of tuples).   Example:
"#record.field" will give you an integer representing the position of
'field' in tuples that hold 'record'.

Another idea could be to consider sequenceNumber to be part of the
header and the data part of the payload, so you define
-record(p2ppacket, {something, sequenceNumber, payload}).

and then various records that you put in the payload field. The downside is that
(Packet#p2ppacket.payload)#p2psyn.synData is a bit ugly to write.

Just some alternatives. The way you chosed to implement it seems to be
an "exploiting the implementation"-approach. Although using element to
access a field in the tuple is too, I admit. I wonder if dialyzer
would complain if it did see these approaches in code.

On 6/19/06, Andrew Lentvorski <bsder@REDACTED> wrote:
> I define some basic packet records.  Every packet has a sequence number,
> and I would like to be able to pull out that sequence number regardless
> of packet type like so:
>
> -module(test).
>
> -compile(export_all).
>
> -record(u_P2PGen, {sequenceNumber}).
> -record(u_P2PSyn, {sequenceNumber, synData}).
> -record(u_P2PFin, {sequenceNumber, finData}).
>
> test() ->
>      Q0 = queue:new(),
>      Q1 = queue:in(#u_P2PSyn{sequenceNumber=1, synData=foo}, Q0),
>      Q2 = queue:in(#u_P2PFin{sequenceNumber=9, finData=bar}, Q1),
>      io:format("Q2: ~p~n", [Q2]),
>
>      {{value, P0}, Q3} = queue:out(Q2),
>      io:format("P0: ~p~n", [P0]),
>      io:format("SN: ~p~n", [P0#u_P2PGen.sequenceNumber]).
>
> Obviously, with different types of packets hitting the queue, I don't
> know a priori which packet type it is.  Thus why I use a generic packet
> to get at the sequence number.
>
> My question is: Is this "downcast" the only/best way of doing this kind
> generic handling?
>
> Thanks,
> -a
>



More information about the erlang-questions mailing list