18 Jul 2013, 15:37
Generic-user-small

Patrick Schless (1 post)

SPOILER - solution in post - SPOILER

I’m working on the exercises in chapter 7, and I’m confused about the bit syntax.

For term_to_packet, I think I have a decent solution:

term_to_packet(Term) ->
  Bin = term_to_binary(Term),
  << (bit_size(Bin) div 8):32, Bin/binary >>.

For the inverse, I want to grab the byte-count from the first 32 bits, then read 8 times that number for the payload. Something like:

packet_to_term(Packet) ->
  << BinSize:32/integer, Bin:(BinSize*8)/binary >> = Packet,
  binary_to_term(Bin).

This doesn’t compile, though:

85> c(ch7).
ch7.erl:18: illegal bit size
ch7.erl:18: Warning: variable 'BinSize' is unused
error

Getting rid of the multiplier (“*8”) not only compiles, but also gives the right answer, which doesn’t make sense to me because I thought the size specifier was bits, not bytes. So it seems like it (without the multiplier) should only be grabbing the first BinSize bits, instead of the first BinSize bytes, and should give a badmatch error at runtime.

packet_to_term(Packet) ->
  << BinSize:32/integer, Bin:BinSize/binary >> = Packet,
  binary_to_term(Bin).

86> c(ch7).
{ok,ch7}
87> ch7:packet_to_term(ch7:term_to_packet(asdf)).
asdf
18 Nov 2013, 19:23
Generic-user-small

Jared Summers (1 post)

The unit size on binaries is 8. So <<Bin:3/binary>> would be 24 bits. Also, see page 103. Size must be an integer or something that evaluates to an integer. However, there’s an additional restriction for pattern matching (the left hand side of that =). In that case, size must be either an integer or a variable bound to an integer, other expressions aren’t accepted. In the case of the version that compiles, BinSize is bound to a 32-bit integer, so it is acceptable for specifying the size for Bin.

  You must be logged in to comment