From 7e33c613fcef7cdfe44b93bb7f6da2206f30d7ca Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 4 Oct 2017 10:33:36 +1300 Subject: Rename module to List::Breakdown Not close to any other module on CPAN from what I can tell. Also bump version number. --- MANIFEST | 2 +- Makefile.PL | 8 +- README | 6 +- README.markdown | 6 +- lib/List/Breakdown.pm | 221 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/List/Filters.pm | 221 -------------------------------------------------- t/errors.t | 12 +-- t/words.t | 6 +- 8 files changed, 241 insertions(+), 241 deletions(-) create mode 100644 lib/List/Breakdown.pm delete mode 100644 lib/List/Filters.pm diff --git a/MANIFEST b/MANIFEST index 09eaf65..8c1f69a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,4 +1,4 @@ -lib/List/Filters.pm +lib/List/Breakdown.pm Makefile.PL MANIFEST README diff --git a/Makefile.PL b/Makefile.PL index 54aef50..f6edcf7 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -4,10 +4,10 @@ use warnings; use ExtUtils::MakeMaker; WriteMakefile( - NAME => 'List::Filters', + NAME => 'List::Breakdown', AUTHOR => 'Tom Ryder ', - VERSION_FROM => 'lib/List/Filters.pm', - ABSTRACT_FROM => 'lib/List/Filters.pm', + VERSION_FROM => 'lib/List/Breakdown.pm', + ABSTRACT_FROM => 'lib/List/Breakdown.pm', LICENSE => 'artistic_2', PL_FILES => {}, MIN_PERL_VERSION => '5.006', @@ -19,5 +19,5 @@ WriteMakefile( }, PREREQ_PM => {}, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, - clean => { FILES => 'List-Filters-*' }, + clean => { FILES => 'List-Breakdown-*' }, ); diff --git a/README b/README index b52ef57..829ab1f 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ -List-Filters +List-Breakdown -Filters elements from a list non-uniquely into a specified hash +Breakdown elements from a list non-uniquely into a specified hash structure, which can be nested, that pass subroutines or match regular expressions. @@ -19,7 +19,7 @@ SUPPORT AND DOCUMENTATION After installing, you can find documentation for this module with the perldoc command. - perldoc List::Filters + perldoc List::Breakdown LICENSE AND COPYRIGHT diff --git a/README.markdown b/README.markdown index 6d5e8e4..b4cdd74 100644 --- a/README.markdown +++ b/README.markdown @@ -1,7 +1,7 @@ -List::Filters +List::Breakdown ============= -Filters elements from a list non-uniquely into a specified hash +Filter elements from a list non-uniquely into a specified hash structure, which can be nested, that pass subroutines or match regular expressions. @@ -22,7 +22,7 @@ Support and Documentation After installing, you can find documentation for this module with the perldoc command. - perldoc List::Filters + perldoc List::Breakdown License and Copyright --------------------- diff --git a/lib/List/Breakdown.pm b/lib/List/Breakdown.pm new file mode 100644 index 0000000..44efc58 --- /dev/null +++ b/lib/List/Breakdown.pm @@ -0,0 +1,221 @@ +package List::Breakdown; + +# Force me to write this properly +use strict; +use warnings; +use utf8; + +# Target reasonably old Perls +use 5.006; + +# Import required modules +use Carp; + +# Handle exporting in a way Perl v5.6 should tolerate +use base qw(Exporter); +our @EXPORT_OK = 'breakdown'; + +# Specify package version +our $VERSION = 0.06; + +# Dispatch table of functions to handle different ref types for the spec +# hashref's values +my %types = ( + + # If it's a hash, apply breakdown() again as if it were another root-level + # spec + HASH => sub { + my $spec = shift; + return { breakdown( $spec, @_ ) }; + }, + + # If it's a subroutine, return a arrayref of all elements for which it + # returns true + CODE => sub { + my $sub = shift; + return [ grep { $sub->() } @_ ]; + }, + + # If it's a regular expression, return an arrayref of all elements it + # matches + Regexp => sub { + my $re = shift; + return [ grep { $_ =~ $re } @_ ]; + }, +); + +# Given a spec and a list of items, filter them into a hash of the same +# structure +sub breakdown { + my ( $spec, @items ) = @_; + + # Check the spec is a hashref + ref $spec eq 'HASH' + or croak 'HASH reference expected for first argument'; + + # Start building a results hash + my %results; + for my $key ( keys %{$spec} ) { + + # Check that the value for this key is a reference + my $ref = ref $spec->{$key} + or croak "Reference expected for '$key'"; + + # Check it's a reference we understand + exists $types{$ref} + or croak "Unhandled ref type $ref for '$key'"; + + # Apply the appropriate subroutine for this reference type to the list + # of items + $results{$key} = $types{$ref}->( $spec->{$key}, @items ); + } + + # Return the constructed result set + return %results; +} + +1; + +__END__ + +=pod + +=for stopwords +sublists Unhandled tradename licensable MERCHANTABILITY + +=head1 NAME + +List::Breakdown - Build list sublists matching conditions + +=head1 VERSION + +Version 0.06 + +=head1 DESCRIPTION + +This module "breaks down" a list--filtering elements from a list into a +specified hash structure, which can be nested. It may be useful in situations +where you have a big list of things to generate reports on or to otherwise +filter into several sublists. + +It differs from the excellent C in the use of subroutine +references for 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. + +You could maybe think of this as a multi-C that returns named results. + +=head1 SYNOPSIS + + 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; + +=head1 SUBROUTINES/METHODS + +=head2 B + +Given a hash reference structure and a list of items, apply each of the +subroutines or regular expressions given as values of the hash reference, +returning a new hash in the same structure with the tests replaced with the +items for which the subroutine returns true, in the same way as C, or (as +a shortcut) for which the regular expression matched. + +=head1 AUTHOR + +Tom Ryder C<< >> + +=head1 DIAGNOSTICS + +=over 4 + +=item HASH reference expected for first argument + +The first argument that B saw wasn't the hash reference it expects. +That's the only format a spec is allowed to have. + +=item Reference expected for '%s' + +The value for the named key in the spec was not a reference, and one was +expected. + +=item 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 C, C, and C. + +=back + +=head1 DEPENDENCIES + +Perl 5.6 and the core modules C and C. + +=head1 CONFIGURATION AND ENVIRONMENT + +None required. + +=head1 INCOMPATIBILITIES + +None known. + +=head1 BUGS AND LIMITATIONS + +Definitely. This is a very early release. Please report any bugs or feature +requests to C. + +=head1 SUPPORT + +You can find documentation for this module with the C command. + + perldoc List::Breakdown + +=head1 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 the Artistic License (2.0). You may obtain a copy of the full +license at: + + + +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. + +=cut diff --git a/lib/List/Filters.pm b/lib/List/Filters.pm deleted file mode 100644 index f85e9b3..0000000 --- a/lib/List/Filters.pm +++ /dev/null @@ -1,221 +0,0 @@ -package List::Filters; - -# Force me to write this properly -use strict; -use warnings; -use utf8; - -# Target reasonably old Perls -use 5.006; - -# Import required modules -use Carp; - -# Handle exporting in a way Perl v5.6 should tolerate -use base qw(Exporter); -our @EXPORT_OK = 'filter'; - -# Specify package version -our $VERSION = 0.05; - -# Dispatch table of functions to handle different ref types for the spec -# hashref's values -my %types = ( - - # If it's a hash, apply filter() again as if it were another root-level - # spec - HASH => sub { - my $spec = shift; - return { filter( $spec, @_ ) }; - }, - - # If it's a subroutine, return a arrayref of all elements for which it - # returns true - CODE => sub { - my $sub = shift; - return [ grep { $sub->() } @_ ]; - }, - - # If it's a regular expression, return an arrayref of all elements it - # matches - Regexp => sub { - my $re = shift; - return [ grep { $_ =~ $re } @_ ]; - }, -); - -# Given a spec and a list of items, filter them into a hash of the same -# structure -sub filter { - my ( $spec, @items ) = @_; - - # Check the spec is a hashref - ref $spec eq 'HASH' - or croak 'HASH reference expected for first argument'; - - # Start building a results hash - my %results; - for my $key ( keys %{$spec} ) { - - # Check that the value for this key is a reference - my $ref = ref $spec->{$key} - or croak "Reference expected for '$key'"; - - # Check it's a reference we understand - exists $types{$ref} - or croak "Unhandled ref type $ref for '$key'"; - - # Apply the appropriate subroutine for this reference type to the list - # of items - $results{$key} = $types{$ref}->( $spec->{$key}, @items ); - } - - # Return the constructed result set - return %results; -} - -1; - -__END__ - -=pod - -=for stopwords -sublists Unhandled tradename licensable MERCHANTABILITY - -=head1 NAME - -List::Filters - Build list sublists matching conditions - -=head1 VERSION - -Version 0.05 - -=head1 DESCRIPTION - -This module filters elements from a list non-uniquely into a specified hash -structure, which can be nested. It may be useful in situations where you have a -big list of things to generate reports on or to otherwise filter into several -sublists. - -It differs from the excellent C in that it does not require -only one final category for any given item; an item can be in more than one -filter. - -You could maybe think of it as a multi-C that returns named results. - -=head1 SYNOPSIS - - 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 = filter $cats, @words; - -=head1 SUBROUTINES/METHODS - -=head2 B - -Given a hash reference structure and a list of items, apply each of the -subroutines or regular expressions given as values of the hash reference, -returning a new hash in the same structure with the tests replaced with the -items for which the subroutine returns true, in the same way as C, or (as -a shortcut) for which the regular expression matched. - -=head1 AUTHOR - -Tom Ryder C<< >> - -=head1 DIAGNOSTICS - -=over 4 - -=item HASH reference expected for first argument - -The first argument that B saw wasn't the hash reference it expects. -That's the only format a spec is allowed to have. - -=item Reference expected for '%s' - -The value for the named key in the spec was not a reference, and one was -expected. - -=item 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 C, C, and C. - -=back - -=head1 DEPENDENCIES - -Perl 5.6 and the core modules C and C. - -=head1 CONFIGURATION AND ENVIRONMENT - -None required. - -=head1 INCOMPATIBILITIES - -None known. - -=head1 BUGS AND LIMITATIONS - -Definitely. This is a very early release. Please report any bugs or feature -requests to C. - -=head1 SUPPORT - -You can find documentation for this module with the C command. - - perldoc List::Filters - -=head1 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 the Artistic License (2.0). You may obtain a copy of the full -license at: - - - -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. - -=cut diff --git a/t/errors.t b/t/errors.t index 842c344..809b0b3 100644 --- a/t/errors.t +++ b/t/errors.t @@ -6,12 +6,12 @@ use utf8; use Test::More tests => 4; -use List::Filters 'filter'; +use List::Breakdown 'breakdown'; -our $VERSION = 0.05; +our $VERSION = 0.06; my @t = 1 .. 3; -is( eval { filter { a => undef }, @t } || undef, undef, 'error_notref_undef' ); -is( eval { filter { a => 'a' }, @t } || undef, undef, 'error_notref_def' ); -is( eval { filter { a => [] }, @t } || undef, undef, 'error_badref_array' ); -is( eval { filter { a => \{} }, @t } || undef, undef, 'error_badref_double' ); +is( eval { breakdown { a => undef }, @t } || undef, undef, 'error_notref_undef' ); +is( eval { breakdown { a => 'a' }, @t } || undef, undef, 'error_notref_def' ); +is( eval { breakdown { a => [] }, @t } || undef, undef, 'error_badref_array' ); +is( eval { breakdown { a => \{} }, @t } || undef, undef, 'error_badref_double' ); diff --git a/t/words.t b/t/words.t index a2ca767..609e2ff 100644 --- a/t/words.t +++ b/t/words.t @@ -6,9 +6,9 @@ use utf8; use Test::More tests => 1; -use List::Filters 'filter'; +use List::Breakdown 'breakdown'; -our $VERSION = 0.05; +our $VERSION = 0.06; my @words = qw(foo bar baz quux wibble florb); my $filters = { @@ -22,7 +22,7 @@ my $filters = { }, has_ba => qr/ba/msx, }; -my %filtered = filter $filters, @words; +my %filtered = breakdown $filters, @words; my %expected = ( all => [qw(foo bar baz quux wibble florb)], -- cgit v1.2.3