One of the coolest and most thoughtfully implemented features in Ruby is data packing and unpacking. I haven’t encountered such a simple API for working with binary data even in compiled languages like Go, Rust, or C++.
For example, if you need to turn two bytes into a 16-bit integer, it looks like this:
[32, 255].pack('C*').unpack('S>')
=> [8447]
To make it clearer what’s happening, let’s add 1 byte to the result and unpack it back into an array of bytes:
[8447 + 256].pack('S>').unpack('C*')
=> [33, 255]
You can also easily convert bytes into a hexadecimal or binary string:
[32, 255].pack('C*').unpack('H*').first.chars.each_slice(2).map(&:join)
=> ["20", "ff"]
[33, 255].pack('C*').unpack('B*').first.chars.each_slice(8).map(&:join)
=> ["00100001", "11111111"]
And this is just a fraction of all possible use cases.
Have you ever used Array#pack and String#unpack in your projects?