Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does binary-size work in Elixir

Tags:

elixir

I am currently trying to understand how binary-size(number) works in Elixir. In the example from The Little Elixir & OTP Guidebook there is a section where they break apart a 128 byte ID3 tag. The tag has the following properties:

  • 3 byte header
  • 30 byte title tag
  • 30 byte artist tag
  • 30 byte album tag
  • 4 byte year tag
  • Rest is packing

The way in which they extract this in the book is

<< "TAG", title :: binary-size(30), artist :: binary-size(30), album :: binary-size(30), year:: binary-size(4), _ :: binary >>

I am having trouble understanding how each value gets the correct value from binary-size(#num). Maybe it is the order in which the pattern matching is taking place and I am having trouble understand that. Currently I am approaching it as we first pattern match the header which is three bytes since it is hardcoded as "TAG", at this point I'm not sure how we can get the value of 30 bytes from binary-size(30). Is this operation being split up into two separate parts? Are we saying that first from 128, total byte size, we subtract 30 and then assign the value of size(30) to the title, and then carry this updated size to each value in the binary pattern match propagating any changes along the way?

like image 568
cogle Avatar asked Dec 14 '16 00:12

cogle


People also ask

What is binary in Elixir?

A binary is a bitstring where the number of bits is divisible by 8. That means that every binary is a bitstring, but not every bitstring is a binary. We can use the is_bitstring/1 and is_binary/1 functions to demonstrate this.

What is a Charlist?

A group of one or more characters enclosed by [ ] as part of Like operator's right string expression. This list contains single characters and/or character ranges which describe the characters in the list. A range of characters is indicated with a hyphen (-) between two characters.


1 Answers

I think you may be getting confused with how Elixir does it's pattern matching and the syntax it uses.

Firstly I know it isn't really seen anywhere else in syntax but it's binary-size(30) not binary - size(30).

So basically, it's saying that the size of the binary is 30 (e.g. 30 bytes) not binary subtract 30 bytes.

So for example:

iex(1)> string = "binary matching string"
"binary matching string"
iex(2)> <<head::binary-size(1), _rest::binary>> = string
"binary matching string"
iex(3)> head
"b"

So here we are saying match the value of head to the first byte of the string "binary matching string" which means that head is b.

We then assign _rest to match the rest of the binary regardless of size.

We aren't limited to strictly matching bytes however. Since << >> is called a bitstring in elixir, if we leave off binary and just do size, the number passed in is measured in bits so therefore val::binary-size(1) is the same as val::size(8) (well sort of see below).

iex(4)> <<head::size(8), _rest::binary>> = string
"binary matching string"
iex(5)> head
98
iex(6)> <<head>>
"b"

To really understand it better, I would definitely recommend opening up an IEX session and typing h <<>> and reading through that.

like image 188
Harrison Lucas Avatar answered Sep 27 '22 21:09

Harrison Lucas