<commit_before>= Packable Library - Intro

If you need to do read and write binary data, there is of course <tt>Array::pack</tt> and <tt>String::unpack</tt>.
The packable library makes (un)packing nicer, smarter and more powerful.
In case you are wondering why on earth someone would want to do serious (un)packing when YAML & XML are built-in:
I wrote this library to read and write FLV files...

== Feature summary:

=== Explicit forms
Strings, integers & floats have long forms instead of the cryptic letter notation. For example:
    ["answer", 42].pack("C3n")
can be written as:
    ["answer", 42].pack({:bytes => 3}, {:bytes => 2, :endian => :big})
This can look a bit too verbose, so let's introduce shortcuts right away:
=== Shortcuts
Most commonly used options have shortcuts and you can define your own. For example:
    :unsigned_long  <===> {:bytes => 4, :signed => false, :endian => :big}
=== IO
IO classes (File & StringIO) can use (un)packing routines.
For example:
    signature, block_len, temperature = my_file >> [String, :bytes=>3] >> Integer >> :float
The method +each+ also accepts packing options:
    StringIO.new("\000\001\000\002\000\003").each(:short).to_a  ===>  [1,2,3]
=== Custom classes
It's easy to make you own classes (un)packable. All the previous goodies are thus available:
		File.open("great_flick.flv") do |f|
			head = f.read(FLV::Header)<commit_msg>Fix README [DOC]<commit_after>= Packable Library - Intro

If you need to do read and write binary data, there is of course <tt>Array::pack</tt> and <tt>String::unpack</tt>.
The packable library makes (un)packing nicer, smarter and more powerful.
In case you are wondering why on earth someone would want to do serious (un)packing when YAML & XML are built-in:
I wrote this library to read and write FLV files...

== Feature summary:

=== Explicit forms
Strings, integers & floats have long forms instead of the cryptic letter notation. For example:
    ["answer", 42].pack("C3n")
can be written as:
    ["answer", 42].pack({:bytes => 3}, {:bytes => 2, :endian => :big})
This can look a bit too verbose, so let's introduce shortcuts right away:
=== Shortcuts
Most commonly used options have shortcuts and you can define your own. For example:
    :unsigned_long  <===> {:bytes => 4, :signed => false, :endian => :big}
=== IO
IO classes (File & StringIO) can use (un)packing routines.
For example:
    signature, block_len, temperature = my_file >> [String, :bytes=>3] >> Integer >> :float
The method +each+ also accepts packing options:
    StringIO.new("\000\001\000\002\000\003").each(:short).to_a  ===>  [1,2,3]
=== Custom classes
It's easy to make you own classes (un)packable. All the previous goodies are thus available:

		File.open("great_flick.flv") do |f|
			head = f.read(FLV::Header)
{'fraction_non_alphanumeric': 0.1307471264367816, 'fraction_numerical': 0.021551724137931036, 'mean_word_length': 4.397286821705427, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3768284', 'n_tokens_mistral': 911, 'n_tokens_neox': 833, 'n_words': 355}