Defaults-Modern

 view release on metacpan or  search on metacpan

lib/Defaults/Modern.pm  view on Meta::CPAN

use Types::Path::Tiny         ();
use Type::Registry            ();
use Type::Utils               ();
use List::Objects::Types      ();


sub import {
  my $class = shift;
  my $pkg = caller;

  state $known = +{ 
    map {; $_ => 1 } qw/
      all
      autobox_lists 
      moo
    /
  };

  my %params;
  my $idx = 0;
  my $typelibs;
  PARAM: for my $item (@_) {
    my $current = $idx++;
    if ($item eq 'with_types' || $item eq '-with_types') {
      # backwards-compat ; may go away someday
      Carp::carp(
        "'with_types' option is deprecated; ",
        "'use TYPELIB -all' after 'use Defaults::Modern;' instead"
      );
      $typelibs = $_[$idx];
      splice @_, $current, 2;
      if (ref $typelibs) {
        Carp::croak "with_types should be an ARRAY, got $typelibs"
          if Scalar::Util::reftype($typelibs) ne 'ARRAY';
      } else {
        $typelibs = [ $typelibs ]
      }
      next PARAM
    }

    my $opt = lc($item =~ s/^(?:[-:])//r);
    Carp::croak("$class does not export $opt") unless $known->{$opt};

    if ($opt eq 'all') {
      $params{$_} = 1 for grep {; $_ ne 'all' } keys %$known;
      next PARAM
    }

    $params{$opt} = 1;
  }

  # Us
  Defaults::Modern::Define->import::into($pkg);

  # Core
  Carp->import::into($pkg,
    qw/carp croak confess/,
  );

  Scalar::Util->import::into($pkg,
    qw/blessed reftype weaken/,
  );
  
  # Pragmas
  strictures->import::into($pkg, version => 2);
  bareword::filehandles->unimport;
  indirect->unimport(':fatal');
  warnings->unimport('once');
  if ($] >= 5.018) {
    warnings->unimport('experimental');
  }

  feature->import(':5.14');
  feature->unimport('switch');

  match::simple->import::into($pkg);
  true->import;

  # External functionality

  state $fp_defaults = +{
    strict                => 1,
    default_arguments     => 1,
    named_parameters      => 1,
    types                 => 1,
    reify_type            => sub {
      state $guard = do { require Type::Utils };
      Type::Utils::dwim_type($_[0], for => $_[1])
    },
  };

  Function::Parameters->import(
    +{
      fun => {
        name                  => 'optional',
        %$fp_defaults
      },
      method => {
        name                  => 'required',
        attributes            => ':method',
        shift                 => '$self',
        invocant              => 1,
        %$fp_defaults
      }
    }
  );

  Path::Tiny->import::into($pkg, 'path');

  PerlX::Maybe->import::into($pkg, qw/maybe provided/);

  Quote::Code->import::into($pkg, qw/qc qcw qc_to/);

  Try::Tiny->import::into($pkg);
  Switch::Plain->import;

  $params{autobox_lists} ?
    List::Objects::WithUtils->import::into($pkg, 'all')
    : List::Objects::WithUtils->import::into($pkg);

  # Types

lib/Defaults/Modern.pm  view on Meta::CPAN

    # define keyword for defining constants ->
    define ARRAY_MAX = 10;

    # Moo(se) with types ->
    use Moo;

    has myarray => (
      is      => 'ro',
      isa     => ArrayObj,
      writer  => '_set_myarray',
      coerce  => 1,
      builder => sub { [] },
    );

    # Method with optional positional param and implicit $self ->
    method slice_to_max (Int $max = -1) {
      my $arr = $self->myarray;
      $self->_set_myarray( 
        $arr->sliced( 0 .. $max >= 0 ? $max : ARRAY_MAX )
      )
    }
  }

  # Optionally autobox list-type refs via List::Objects::WithUtils ->
  use Defaults::Modern 'autobox_lists';
  my $obj = +{ foo => 'bar', baz => 'quux' }->inflate;
  my $baz = $obj->baz;

  # See DESCRIPTION for complete details on imported functionality.

=head1 DESCRIPTION

Yet another approach to writing Perl in a modern style.

. . . also saves me extensive typing ;-)

When you C<use Defaults::Modern>, you get:

=over

=item *

L<strictures> (version 2), which enables L<strict> and makes most warnings
fatal; additionally L<bareword::filehandles> and L<indirect> method calls are
disallowed explicitly (not just in development environments)

=item *

The C<v5.14> feature set (C<state>, C<say>, C<unicode_strings>, C<array_base>) -- except for
C<switch>, which is deprecated in newer perls (and L<Switch::Plain> is
provided anyway).

C<experimental> warnings are also disabled on C<v5.18+>.

=item *

B<carp>, B<croak>, and B<confess> error reporting tools from L<Carp>

=item *

B<blessed>, B<reftype>, and B<weaken> utilities from L<Scalar::Util>

=item *

All of the L<List::Objects::WithUtils> object constructors (B<array>,
B<array_of>, B<immarray>, B<immarray_of>, B<hash>, B<hash_of>, B<immhash>,
B<immhash_of>)

=item *

B<fun> and B<method> keywords from L<Function::Parameters> configured to
accept L<Type::Tiny> types (amongst other reasonably sane defaults including
arity checks)

=item *

The full L<Types::Standard> set and L<List::Objects::Types> -- useful in
combination with L<Function::Parameters> (see the L</SYNOPSIS> and
L<Function::Parameters> POD)

=item *

B<try> and B<catch> from L<Try::Tiny>

=item *

The B<path> object constructor from L<Path::Tiny> and related types/coercions
from L<Types::Path::Tiny>

=item *

B<maybe> and B<provided> definedness-checking syntax sugar from L<PerlX::Maybe>

=item *

A B<define> keyword for defining constants based on L<PerlX::Define>

=item *

The B<|M|> match operator from L<match::simple>

=item *

The B<sswitch> and B<nswitch> switch/case constructs from L<Switch::Plain>

=item *

The B<qc>, B<qcw>, and B<qc_to> code-interpolating keywords from
L<Quote::Code> (as of Defaults::Modern C<v0.11.1>)

=item *

L<true>.pm so you can skip adding '1;' to all of your modules

=back

If you import the tag C<autobox_lists>, ARRAY and HASH type references are autoboxed
via L<List::Objects::WithUtils>:

  use Defaults::Modern 'autobox_lists';
  my $itr = [ 1 .. 10 ]->natatime(2);



( run in 1.137 second using v1.01-cache-2.11-cpan-39bf76dae61 )