# 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](http://search.cpan.org/perldoc?Data::Perl).

## Arrays

__array__ ([List::Objects::WithUtils::Array](http://search.cpan.org/perldoc?List::Objects::WithUtils::Array)) provides basic mutable
ARRAY-type objects.  Behavior is defined by
[List::Objects::WithUtils::Role::Array](http://search.cpan.org/perldoc?List::Objects::WithUtils::Role::Array); look there for documentation on
available methods.

__immarray__ is imported from [List::Objects::WithUtils::Array::Immutable](http://search.cpan.org/perldoc?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](http://search.cpan.org/perldoc?Type::Tiny)\-compatible type-checking array objects
that can coerce and check their values as they are added; see
[List::Objects::WithUtils::Array::Typed](http://search.cpan.org/perldoc?List::Objects::WithUtils::Array::Typed).

__immarray\_of__ provides immutable type-checking arrays; see
[List::Objects::WithUtils::Array::Immutable::Typed](http://search.cpan.org/perldoc?List::Objects::WithUtils::Array::Immutable::Typed).

## Hashes

__hash__ is the basic mutable HASH-type object imported from
[List::Objects::WithUtils::Hash](http://search.cpan.org/perldoc?List::Objects::WithUtils::Hash); see
[List::Objects::WithUtils::Role::Hash](http://search.cpan.org/perldoc?List::Objects::WithUtils::Role::Hash) for documentation.

__immhash__ provides immutable (restricted) hashes; see
[List::Objects::WithUtils::Hash::Immutable](http://search.cpan.org/perldoc?List::Objects::WithUtils::Hash::Immutable).

__hash\_of__ provides [Type::Tiny](http://search.cpan.org/perldoc?Type::Tiny)\-compatible type-checking hash
objects; see [List::Objects::WithUtils::Hash::Typed](http://search.cpan.org/perldoc?List::Objects::WithUtils::Hash::Typed).

__immhash\_of__ provides immutable type-checking hashes; see
[List::Objects::WithUtils::Hash::Immutable::Typed](http://search.cpan.org/perldoc?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](http://search.cpan.org/perldoc?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](http://search.cpan.org/perldoc?List::Objects::WithUtils::Role::Array) for documentation on the basic set of
`array()` methods.

[List::Objects::WithUtils::Role::Array::WithJunctions](http://search.cpan.org/perldoc?List::Objects::WithUtils::Role::Array::WithJunctions) for documentation on `array()`
junction-returning methods.

[List::Objects::WithUtils::Role::Hash](http://search.cpan.org/perldoc?List::Objects::WithUtils::Role::Hash) for documentation regarding `hash()`
methods.

[List::Objects::WithUtils::Array::Immutable](http://search.cpan.org/perldoc?List::Objects::WithUtils::Array::Immutable) for more on `immarray()`
immutable arrays.

[List::Objects::WithUtils::Array::Typed](http://search.cpan.org/perldoc?List::Objects::WithUtils::Array::Typed) for more on `array_of()`
type-checking arrays.

[List::Objects::WithUtils::Array::Immutable::Typed](http://search.cpan.org/perldoc?List::Objects::WithUtils::Array::Immutable::Typed) for more on
`immarray_of()` immutable type-checking arrays.

[List::Objects::WithUtils::Hash::Typed](http://search.cpan.org/perldoc?List::Objects::WithUtils::Hash::Typed) for more on `hash_of()`
type-checking hashes.

[List::Objects::WithUtils::Hash::Immutable::Typed](http://search.cpan.org/perldoc?List::Objects::WithUtils::Hash::Immutable::Typed) for more on
`immhash_of()` immutable type-checking hashes.

[List::Objects::WithUtils::Autobox](http://search.cpan.org/perldoc?List::Objects::WithUtils::Autobox) for details on autoboxing.

The [Lowu](http://search.cpan.org/perldoc?Lowu) module for a convenient importer shortcut.

[List::Objects::Types](http://search.cpan.org/perldoc?List::Objects::Types) for relevant [Type::Tiny](http://search.cpan.org/perldoc?Type::Tiny) types.

[MoopsX::ListObjects](http://search.cpan.org/perldoc?MoopsX::ListObjects) for integration with [Moops](http://search.cpan.org/perldoc?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](http://search.cpan.org/perldoc?Data::Perl) by Matthew
Phillips (CPAN: MATTP), haarg, and others.

Immutable array objects were inspired by [Const::Fast](http://search.cpan.org/perldoc?Const::Fast) by Leon Timmermans
(CPAN: LEONT)

Junctions are adapted from [Perl6::Junction](http://search.cpan.org/perldoc?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](http://search.cpan.org/perldoc?List::Util)

[List::MoreUtils](http://search.cpan.org/perldoc?List::MoreUtils)

[List::UtilsBy](http://search.cpan.org/perldoc?List::UtilsBy)
