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, but via the 'Lowu' shortcut:
      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 $wanted = array(
        +{ id => '400', user => 'bob' },
        +{ id => '600', user => 'suzy' },
        +{ id => '700', user => 'fred' },
      )->first(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');

      # Hashes can be inflated to objects:
      my $obj = $hash->inflate;
      $snacks = $obj->snacks;

      # Chained method examples; methods that return 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 eq 'snacks' ) {
        ...    
      }
      if ( $hash->values->all_items > 10 ) {
        ...
      }

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

      # Type-checking hashes:
      use List::Objects::WithUtils 'hash_of';
      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.

  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 functional 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,
    providing 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.

  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;
      with 'List::Objects::WithUtils::Role::Array',
           'List::Objects::WithUtils::Role::Array::WithJunctions';

      # An easy 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' }

      # ...

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::Role::Hash for documentation regarding
    "hash()" 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::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 inspired by Const::Fast by Leon Timmermans
    (CPAN: LEONT)

    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)

    Much of this code simply wraps other widely-used modules, including:

    List::Util

    List::MoreUtils

    List::UtilsBy

