Provided by: liblist-objects-withutils-perl_2.028003-3_all bug

NAME

       List::Objects::WithUtils - List objects, kitchen sink included

SYNOPSIS

         ## A small sample; consult the description, below, for links to
         ## extended documentation

         # Import all object constructor functions:
         #   array immarray array_of immarray_of
         #   hash immhash hash_of immhash_of
         use List::Objects::WithUtils;

         # Import all of the above plus autoboxing:
         use List::Objects::WithUtils ':all';
         # Same as above, but shorter:
         use Lowu;

         # Most methods returning lists return new objects; chaining is easy:
         array(qw/ aa Ab bb Bc bc /)
           ->grep(sub { /^b/i })
           ->map(sub  { uc })
           ->uniq
           ->all;   # ( 'BB', 'BC' )

         # Useful utilities from other list modules are available:
         my $want_idx = array(
           +{ id => '400', user => 'bob' },
           +{ id => '600', user => 'suzy' },
           +{ id => '700', user => 'fred' },
         )->first_index(sub { $_->{id} > 500 });

         my $itr = array( 1 .. 7 )->natatime(3);
         while ( my @nextset = $itr->() ) {
           ...
         }

         my $meshed = array(qw/ a b c d /)
           ->mesh( array(1 .. 4) )
           ->all;   # ( 'a', 1, 'b', 2, 'c', 3, 'd', 4 )

         my ($evens, $odds) = array( 1 .. 20 )
           ->part(sub { $_[0] & 1 })
           ->all;

         my $sorted = array(
           +{ name => 'bob',  acct => 1 },
           +{ name => 'fred', acct => 2 },
           +{ name => 'suzy', acct => 3 },
         )->sort_by(sub { $_->{name} });

         # array() objects are mutable:
         my $mutable = array(qw/ foo bar baz /);
         $mutable->insert(1, 'quux');
         $mutable->delete(2);

         # ... or use immarray() immutable arrays:
         my $static = immarray( qw/ foo bar baz / );
         $static->set(0, 'quux');  # dies
         $static->[0] = 'quux';    # dies
         push @$static, 'quux';    # dies

         # Construct a hash:
         my $hash  = hash( foo => 'bar', snacks => 'cake' );

         # You can set multiple keys in one call:
         $hash->set( foobar => 'baz', pie => 'cherry' );

         # ... which is useful for merging in another (plain) hash:
         my %foo = ( pie => 'pumpkin', snacks => 'cheese' );
         $hash->set( %foo );

         # ... or another hash object:
         my $second = hash( pie => 'key lime' );
         $hash->set( $second->export );

         # Retrieve one value as a simple scalar:
         my $snacks = $hash->get('snacks');

         # ... or retrieve multiple values as an array-type object:
         my $vals = $hash->get('foo', 'foobar');

         # Take a hash slice of keys, return a new hash object
         # consisting of the retrieved key/value pairs:
         my $slice = $hash->sliced('foo', 'pie');

         # Arrays inflate to hash objects:
         my $items = array( qw/ foo bar baz/ )->map(sub { $_ => 1 })->inflate;
         if ($items->exists('foo')) {
           # ...
         }

         # Hashes inflate to simple objects with accessors:
         my $obj = $hash->inflate;
         $snacks = $obj->snacks;

         # Methods returning multiple values typically return new array-type objects:
         my @match_keys = $hash->keys->grep(sub { m/foo/ })->all;
         my @match_vals = $hash->values->grep(sub { m/bar/ })->all;

         my @sorted_pairs = hash( foo => 2, bar => 3, baz => 1)
           ->kv
           ->sort_by(sub { $_->[1] })
           ->all;  # ( [ baz => 1 ], [ foo => 2 ], [ bar => 3 ] )

         # Perl6-inspired Junctions:
         if ( $hash->keys->any_items == qr/snacks/ ) {
           # ... hash has key(s) matching /snacks/ ...
         }
         if ( $hash->values->all_items > 10 ) {
           # ... all hash values greater than 10 ...
         }

         # Type-checking arrays via Type::Tiny:
         use Types::Standard -all;
         my $int_arr = array_of Int() => 1 .. 10;

         # Type-checking hashes:
         use Types::Standard -all;
         my $int_hash = hash_of Int() => (foo => 1, bar => 2);

         # Native list types can be autoboxed:
         use List::Objects::WithUtils 'autobox';
         my $foo = [ qw/foo baz bar foo quux/ ]->uniq->sort;
         my $bar = +{ a => 1, b => 2, c => 3 }->values->sort;

         # Autoboxing is lexically scoped like normal:
         { no List::Objects::WithUtils::Autobox;
           [ 1 .. 10 ]->shuffle;  # dies
         }

DESCRIPTION

       A set of roles and classes defining an object-oriented interface to Perl hashes and arrays
       with useful utility methods, junctions, type-checking ability, and optional autoboxing.
       Originally derived from Data::Perl.

   Uses
       The included objects are useful as-is but are largely intended for use as data container
       types for attributes. This lends a more natural object-oriented syntax; these are
       particularly convenient in combination with delegated methods, as in this example:

         package Some::Thing;
         use List::Objects::WithUtils;
         use Moo;

         has items => (
           is      => 'ro',
           builder => sub { array },
           handles => +{
             add_items   => 'push',
             get_items   => 'all',
             items_where => 'grep',
           },
         );

         # ... later ...
         my $thing = Some::Thing->new;
         $thing->add_items(@more_items);
         # Operate on all positive items:
         for my $item ($thing->items_where(sub { $_ > 0 })->all) {
           ...
         }

       List::Objects::Types provides Type::Tiny-based types & coercions matching the list objects
       provided by this distribution. These integrate nicely with typed or untyped list objects:

         package Accounts;
         use List::Objects::Types -types;
         use Moo 2;

         has usergroups => (
           is        => 'ro',
           # +{ $group => [ [ $usr => $id ], ... ] }
           # Coerced to objects all the way down:
           isa       => TypedHash[ TypedArray[ArrayObj] ],
           coerce    => 1,
           builder   => sub { +{} },
         );

         # ... later ...
         my $users_in_grp = $accts->usergroups
           ->get($some_group)
           ->grep(sub { $_[0]->get(0) });

   Objects
       Arrays

       array (List::Objects::WithUtils::Array) provides basic mutable ARRAY-type objects.
       Behavior is defined by List::Objects::WithUtils::Role::Array; look there for documentation
       on available methods.

       immarray is imported from List::Objects::WithUtils::Array::Immutable and operates much
       like an array, except methods that mutate the list are not available; using immutable
       arrays promotes safer programming patterns.

       array_of provides Type::Tiny-compatible type-checking array objects that can coerce and
       check their values as they are added; see List::Objects::WithUtils::Array::Typed.

       immarray_of provides immutable type-checking arrays; see
       List::Objects::WithUtils::Array::Immutable::Typed.

       Hashes

       hash is the basic mutable HASH-type object imported from List::Objects::WithUtils::Hash;
       see List::Objects::WithUtils::Role::Hash for documentation.

       immhash provides immutable (restricted) hashes; see
       List::Objects::WithUtils::Hash::Immutable.

       hash_of provides Type::Tiny-compatible type-checking hash objects; see
       List::Objects::WithUtils::Hash::Typed.

       immhash_of provides immutable type-checking hashes; see
       List::Objects::WithUtils::Hash::Immutable::Typed.

   Importing
       A bare import list ("use List::Objects::WithUtils;") will import all of the object
       constructor functions described above; they can also be selectively imported, e.g.:

         use List::Objects::WithUtils 'array_of', 'hash_of';

       Importing autobox lexically enables List::Objects::WithUtils::Autobox, which provides
       List::Objects::WithUtils::Array or List::Objects::WithUtils::Hash methods for native ARRAY
       and HASH types.

       Importing all or :all will import all of the object constructors and additionally turn
       autobox on; "use Lowu;" is a shortcut for importing all.

   Debugging
       Most methods belonging to these objects are heavily micro-optimized -- at the cost of
       useful error handling.

       Since there are few built-in argument checks, a mistake in your code can frequently lead
       to slightly cryptic errors from the perl side:

         > my $pos;  # whoops, I'm still undefined later:
         > if ($arr->exists($pos)) { ... }
         Use of uninitialized value in numeric le (<=) at $useless_lib_lineno

       ... in which case Devel::Confess is likely to improve your quality of life by providing a
       real backtrace:

         $ perl -d:Confess my_app.pl
         Use of uninitialized value in numeric le (<=) at ...
           [...]::Array::exists(ARRAY(0x8441068), undef) called at ...

   Subclassing
       The importer for this package is somewhat flexible; a subclass can override import to pass
       import tags and a target package by feeding this package's "import()" a HASH:

         # Subclass and import to target packages (see Lowu.pm f.ex):
         package My::Defaults;
         use parent 'List::Objects::WithUtils';
         sub import {
           my ($class, @params) = @_;
           $class->SUPER::import(
             +{
               import => [ 'autobox', 'array', 'hash' ],
               to     => scalar(caller)
             }
           )
         }

       Functionality is mostly defined by Roles.  For example, it's easy to create your own array
       class with new methods:

         package My::Array::Object;
         use Role::Tiny::With;
         # Act like List::Objects::WithUtils::Array:
         with 'List::Objects::WithUtils::Role::Array',
              'List::Objects::WithUtils::Role::Array::WithJunctions';

         # One way to add your own functional interface:
         use Exporter 'import';  our @EXPORT = 'my_array';
         sub my_array { __PACKAGE__->new(@_) }

         # ... add/override methods ...

       ... in which case you may want to also define your own hash subclass that overrides
       "array_type" to produce your preferred arrays:

         package My::Hash::Object;
         use Role::Tiny::With;
         with 'List::Objects::WithUtils::Role::Hash';

         use Exporter 'import';  our @EXPORT = 'my_hash';
         sub my_hash { __PACKAGE__->new(@_) }

         sub array_type { 'My::Array::Object' }

         # ... add/override methods ...

SEE ALSO

       List::Objects::WithUtils::Role::Array for documentation on the basic set of "array()"
       methods.

       List::Objects::WithUtils::Role::Array::WithJunctions for documentation on "array()"
       junction-returning methods.

       List::Objects::WithUtils::Array::Immutable for more on "immarray()" immutable arrays.

       List::Objects::WithUtils::Array::Typed for more on "array_of()" type-checking arrays.

       List::Objects::WithUtils::Array::Immutable::Typed for more on "immarray_of()" immutable
       type-checking arrays.

       List::Objects::WithUtils::Role::Hash for documentation regarding "hash()" methods.

       List::Objects::WithUtils::Hash::Immutable for more on "immhash()" immutable hashes.

       List::Objects::WithUtils::Hash::Typed for more on "hash_of()" type-checking hashes.

       List::Objects::WithUtils::Hash::Immutable::Typed for more on "immhash_of()" immutable
       type-checking hashes.

       List::Objects::WithUtils::Autobox for details on autoboxing.

       The Lowu module for a convenient importer shortcut.

       List::Objects::Types for relevant Type::Tiny types.

       MoopsX::ListObjects for integration with Moops class-building sugar.

AUTHOR

       Jon Portnoy <avenj@cobaltirc.org>

       Licensed under the same terms as Perl.

       The original Array and Hash roles were derived from Data::Perl by Matthew Phillips (CPAN:
       MATTP), haarg, and others.

       Immutable array objects were originally inspired by Const::Fast by Leon Timmermans (CPAN:
       LEONT), but now use "tie".

       Junctions are adapted from Perl6::Junction by Carl Franks (CPAN: CFRANKS)

       Most of the type-checking code and other useful additions were contributed by Toby Inkster
       (CPAN: TOBYINK)

       A significant portion of this code simply wraps other widely-used modules, especially:

       List::Util

       List::UtilsBy

       Type::Tiny

       Inspiration for a few pieces comes from the "classic" (version 0.33) List::MoreUtils.