diff options
Diffstat (limited to 'README.markdown')
-rw-r--r-- | README.markdown | 349 |
1 files changed, 0 insertions, 349 deletions
diff --git a/README.markdown b/README.markdown deleted file mode 100644 index 5eb1b99..0000000 --- a/README.markdown +++ /dev/null @@ -1,349 +0,0 @@ -# NAME - -List::Breakdown - Build sublist structures matching conditions - -# VERSION - -Version 0.19 - -# SYNOPSIS - - use List::Breakdown 'breakdown'; - ... - my @words = qw(foo bar baz quux wibble florb); - my $cats = { - all => sub { 1 }, - has_b => sub { m/ b /msx }, - has_w => sub { m/ w /msx }, - length => { - 3 => sub { length == 3 }, - 4 => sub { length == 4 }, - long => sub { length > 4 }, - }, - has_ba => qr/ba/msx, - }; - my %filtered = breakdown $cats, @words; - -This puts the following structure in `%filtered`: - - ( - all => ['foo', 'bar', 'baz', 'quux', 'wibble', 'florb'], - has_b => ['bar', 'baz', 'wibble', 'florb'], - has_w => ['wibble'], - length => { - 3 => ['foo', 'bar', 'baz'], - 4 => ['quux'], - long => ['wibble', 'florb'], - }, - has_ba => ['bar', 'baz'], - ) - -# DESCRIPTION - -This module assists you in making a _breakdown_ of a list, copying and -filtering its items into a structured bucket layout according to your -specifications. Think of it as a syntax for [`grep`](https://metacpan.org/pod/perlfunc#grep-BLOCK-LIST) that returns named and structured results from one list. - -It differs from the excellent [List::Categorize](https://metacpan.org/pod/List::Categorize) in the use -of references to define each category, and in not requiring only one final -category for any given item; an item can end up in the result set for more than -one filter. - -If you want to divide or _partition_ your list so that each item can only -appear in one category, you may want either -[List::MoreUtils](https://metacpan.org/pod/List::MoreUtils#Partitioning) or possibly -[Set::Partition](https://metacpan.org/pod/Set::Partition) instead. - -# SUBROUTINES/METHODS - -## `breakdown(\%spec, @items)` - -This is the only exportable subroutine. Given a hash reference structure and a -list of items, it applies each of the referenced values as tests, returning a -new hash in the same structure with the references replaced with the matching -items, in the same way as [`grep`](https://metacpan.org/pod/perlfunc#grep-BLOCK-LIST). - -There are two shortcut syntaxes for a value in the `\%spec` structure: - -- `ARRAY` - - If the referenced array has exactly two items, it will be interpreted as - defining numeric bounds `[lower,upper)` for its values. `undef` can be used - to denote negative or positive infinity. Any other number of items is a fatal - error. - -- `Regexp` - - This will be interpreted as a pattern for the list items to match. - -Additionally, if the value is a `HASH` reference, it can be used to make a -sub-part of the structure, as demonstrated in the `length` key of the example -`\%spec` given in [SYNOPSIS](#synopsis). - -# EXAMPLES - -## Collecting troublesome records - -Suppose you have a list of strings from a very legacy system that you need to -regularly check for problematic characters, alerting you to problems with an -imperfect Perl parser: - - my @records = ( - "NEW CUSTOMER John O''Connor\r 2017-01-01", - "RETURNING CUSTOMER\tXah Zhang 2016-01-01", - "CHECK ACCOUNT Pierre d'Alun 2016-12-01", - "RETURNING CUSTOMER Aaron Carter 2016-05-01", - ); - -You could have a bucket structure like this, using the **pattern syntax**, which -catches certain error types you've seen before for review: - - my %buckets = ( - bad_whitespace => qr/ [\r\t] /msx, - apostrophes => qr/ ' /msx, - double_apostrophes => qr/ '' /msx, - not_ascii => qr/ [^[:ascii:]] /msx, - }; - -Applying the bucket structure like so: - - my %results = breakdown \%buckets, @records; - -The result set would look like this: - - my %expected = ( - bad_whitespace => [ - "NEW CUSTOMER John O''Connor\r 2017-01-01", - "RETURNING CUSTOMER\tXah Lee 2016-01-01", - ], - apostrophes => [ - "NEW CUSTOMER John O''Connor\r 2017-01-01", - 'CHECK ACCOUNT Pierre d\'Alun 2016-12-01', - ], - double_apostrophes => [ - "NEW CUSTOMER John O''Connor\r 2017-01-01", - ], - not_ascii => [ - ], - ); - -Notice that some of the lines appear in more than one list, and that the -`not_ascii` bucket is empty, because none of the items matched it. - -## Monitoring system check results - -Suppose you ran a list of checks with your monitoring system, and now you have -a list of `HASH` references with keys describing each check and its outcome: - - my @checks = ( - { - hostname => 'webserver1', - status => 'OK', - }, - { - hostname => 'webserver2', - status => 'CRITICAL', - }, - { - hostname => 'webserver3', - status => 'WARNING', - }, - { - hostname => 'webserver4', - status => 'OK', - } - ); - -You would like to break the list down by status. You would lay out your buckets -like so, using the **subroutine syntax**: - - my %buckets = ( - ok => sub { $_->{status} eq 'OK' }, - problem => { - warning => sub { $_->{status} eq 'WARNING' }, - critical => sub { $_->{status} eq 'CRITICAL' }, - unknown => sub { $_->{status} eq 'UNKNOWN' }, - }, - ); - -And apply them like so: - - my %results = breakdown \%buckets, @checks; - -For our sample data above, this would yield the following structure in -`%results`: - - ( - ok => [ - { - hostname => 'webserver1', - status => 'OK', - }, - { - hostname => 'webserver4', - status => 'OK', - }, - ], - problem => { - warning => [ - { - hostname => 'webserver3', - status => 'WARNING', - }, - ], - critical => [ - { - hostname => 'webserver2', - status => 'CRITICAL', - }, - ], - unknown => [], - } - ) - -Note the extra level of `HASH` references beneath the `problem` key. - -## Grouping numbers by size - -Suppose you have a list of numbers from your volcanic activity reporting -system, some of which might be merely worrisome, and some others an emergency, -and they need to be filtered to know where to send them: - - my @numbers = ( 1, 32, 3718.4, 0x56, 0777, 3.14, -5, 1.2e5 ); - -You could filter them into buckets like this, using the **interval syntax**: an -`ARRAY` reference with exactly two elements: lower bound (inclusive) first, -upper bound (exclusive) second: - - my $filters = { - negative => [ undef, 0 ], - positive => { - small => [ 0, 10 ], - medium => [ 10, 100 ], - large => [ 100, undef ], - }, - }; - -Applying the bucket structure like so: - - my %filtered = breakdown $filters, @numbers; - -The result set would look like this: - - my %expected = ( - negative => [ -5 ], - positive => { - small => [ 1, 3.14 ], - medium => [ 32, 86 ], - large => [ 3_718.4, 511, 120_000 ], - }, - ); - -Notice that you can express infinity or negative infinity as `undef`. Note -also this is a numeric comparison only. - -# AUTHOR - -Tom Ryder `<tom@sanctum.geek.nz>` - -# DIAGNOSTICS - -- `HASH reference expected for first argument` - - The first argument that `breakdown()` saw wasn't the hash reference it expects. - That's the only format a spec is allowed to have. - -- `Reference expected for '%s'` - - The value for the named key in the spec was not a reference, and one was - expected. - -- `Unhandled ref type %s for '%s'` - - The value for the named key in the spec is of a type that makes no sense to - this module. Legal reference types are `ARRAY`, `CODE`, `HASH`, and - `Regexp`. - -# DEPENDENCIES - -- Perl 5.6.0 or newer -- [base](https://metacpan.org/pod/base) -- [Carp](https://metacpan.org/pod/Carp) -- [Exporter](https://metacpan.org/pod/Exporter) - -# CONFIGURATION AND ENVIRONMENT - -None required. - -# INCOMPATIBILITIES - -None known. - -# BUGS AND LIMITATIONS - -Definitely. This is a very early release. Please report any bugs or feature -requests to `tom@sanctum.geek.nz`. - -# SUPPORT - -You can find documentation for this module with the **perldoc** command. - - perldoc List::Breakdown - -You can also look for information at: - -- RT: CPAN's request tracker (report bugs here) - - [http://rt.cpan.org/NoAuth/Bugs.html?Dist=List-Breakdown](http://rt.cpan.org/NoAuth/Bugs.html?Dist=List-Breakdown) - -- AnnoCPAN: Annotated CPAN documentation - - [http://annocpan.org/dist/List-Breakdown](http://annocpan.org/dist/List-Breakdown) - -- CPAN Ratings - - [http://cpanratings.perl.org/d/List-Breakdown](http://cpanratings.perl.org/d/List-Breakdown) - -- Search CPAN - - [http://search.cpan.org/dist/List-Breakdown/](http://search.cpan.org/dist/List-Breakdown/) - -# LICENSE AND COPYRIGHT - -Copyright (C) 2017 Tom Ryder - -This program is free software; you can redistribute it and/or modify it under -the terms of the Artistic License (2.0). You may obtain a copy of the full -license at: - -[http://www.perlfoundation.org/artistic\_license\_2\_0](http://www.perlfoundation.org/artistic_license_2_0) - -Any use, modification, and distribution of the Standard or Modified Versions is -governed by this Artistic License. By using, modifying or distributing the -Package, you accept this license. Do not use, modify, or distribute the -Package, if you do not accept this license. - -If your Modified Version has been derived from a Modified Version made by -someone other than you, you are nevertheless required to ensure that your -Modified Version complies with the requirements of this license. - -This license does not grant you the right to use any trademark, service mark, -tradename, or logo of the Copyright Holder. - -This license includes the non-exclusive, worldwide, free-of-charge patent -license to make, have made, use, offer to sell, sell, import and otherwise -transfer the Package with respect to any patent claims licensable by the -Copyright Holder that are necessarily infringed by the Package. If you -institute patent litigation (including a cross-claim or counterclaim) against -any party alleging that the Package constitutes direct or contributory patent -infringement, then this Artistic License to you shall terminate on the date -that such litigation is filed. - -Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND -CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR -NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. -UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY -OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. |