It’s a lot of reading/writing binary data, sometimes file related, but more often related to sockets.
I was afraid strings wouldn’t be suitable as the data is unlikely to be utf8 friendly. That’s why I’m using IO::Memory and u8 slices and arrays instead.
This
"a\tlocalhost\x06\x02\x04\x00\x00\x80\x01D\xF8A3\xB7\xED\x9B\x98\x85\xEE\x80\xAA#x\x19\t\xCC\xEF\xA8i\xF5N6\xC3R\x81\x1EM\x05\xA8\xBF\xDE\x1E\xEB}\x8Bv<\xB0~\x01\x1C\xEF\x94\xD2\xE7\xD0\xE3
\x9E\xEBZD\x1CC^.Yf\xC1B$\xCC.\xDE\x13K\xA9\x92\xD5k\xA8\xBC\xED$\x11\xCD\xA7R\xB1\xFB\xEA\x7F\x16\x9F\xF0\xB3h\t\xC3\x03\x95\xD0\x01\xC1)O\xA6V\xBE,ex\x04\xA3H\xFA\x1A\xF0\xF1$n\xA5\xA5\x1Ea\xC6%C8\x1A:\fUT@\xAB\xCD\x10\xE0\xD0\xBEeJ\x83\x19+\x8F\xE6,=\xEC\x92\xA0\xD5"`
would be so much nicer to read than
Bytes[97, 9, 108, 111, 99, 97, 108, 104, 111, 115, 116, 6, 2, 4, 0, 0, 128, 1, 68, 248, 65, 51, 183, 237, 155, 152, 133, 238, 128, 170, 35, 120, 25, 9, 204, 239, 168, 105, 245, 78, 54, 195, 82, 129, 30, 77, 5, 168, 191, 222, 30, 235, 125, 139, 118, 60, 176, 126, 1, 28, 239, 148, 210, 231, 208, 227, 96, 158, 235, 90, 68, 28, 67, 94, 46, 89, 102, 193, 66, 36, 204, 46, 222, 19, 75, 169, 146, 213, 107, 168, 188, 237, 36, 17, 205, 167, 82, 177, 251, 234, 127, 22, 159, 240, 179, 104, 9, 195, 3, 149, 208, 1, 193, 41, 79, 166, 86, 190, 44, 101, 120, 4, 163, 72, 250, 26, 240, 241, 36, 110, 165, 165, 30, 97, 198, 37, 67, 56, 26, 58, 12, 85, 84, 64, 171, 205, 16, 224, 208, 190, 101, 74, 131, 25, 43, 143, 230, 44, 61, 236, 146, 160, 213]
While it might look not much different regarding readability at first glance, it usually really is, either because of actual ascii strings (like the “localhost” in my example) or to compare it with hexeditors, outputs from other software, etc. The longer the data fragments are, the more often you have somewhere some recognisable ascii in them, which I can use as reference points during debugging (currently I spend a lot of time counting bytes or sit there with two fingers on my screen, slowly comparing byte after byte of my actual output with the data I try to get). This would still happen for example in ruby, but much less, as I could skip huge parts.
It’s also so much easier and faster to recognise when data is in a wrong format (for example when encoding and encryption steps are involved and some step has been missed or with the wrong format, etc). Like here for example: Bytes[182, 96, 93, 233, 226, 42, 74, 124, 203, 237, 137, 245, 209, 136, 127, 165]
versus Bytes [98, 54, 54, 48, 53, 100, 101, 57, 101, 50, 50, 97, 52, 97, 55, 99, 99, 98, 101, 100, 56, 57, 102, 53, 100, 49, 56, 56, 55, 102, 97, 53]
is much harder in order to recognise a difference, bit it would become immediately obvious as in "\xB6
]\xE9\xE2*J|\xCB\xED\x89\xF5ш\u007F\xA5"versus
“b6605de9e22a4a7ccbed89f5d1887fa5”` (could be an example for hashed data, one time binary, the other time as hex output, like the hmac hash method of OpenSSL offers both)
It becomes even more inconvenient when I want to use some string in code (fixed text, eg. ascii readable file headers) - currently I convert those in ruby, and copy/paste the array of u8 values to my crystal source, because I also don’t want to have it converted from string to byte during runtime (but it would be nice to be able to just use anyway the ascii representation already in my code)