Import-Base

 view release on metacpan or  search on metacpan

lib/Import/Base.pm  view on Meta::CPAN

Which is equivalent to:

    package My::Module;
    use strict;
    use warnings;
    use feature qw( :5.14 );

Now when we want to change our feature set, we only need to edit one file!

=head2 Import Bundles

In addition to a set of modules, we can also create optional bundles with the
C<%IMPORT_BUNDLES> package variable.

    package My::Bundles;
    use parent 'My::Base';

    # Modules that will always be included
    our @IMPORT_MODULES
        experimental => [qw( signatures )],
    );

    # Named bundles to include
    our %IMPORT_BUNDLES = (
        Class => [qw( Moose MooseX::Types )],
        Role => [qw( Moose::Role MooseX::Types )],
        Test => [qw( Test::More Test::Deep )],
    );

Now we can choose one or more bundles to include:

    # lib/MyClass.pm
    use My::Base 'Class';

    # t/mytest.t
    use My::Base 'Test';

    # t/lib/MyTest.pm
    use My::Base 'Test', 'Class';

Bundles must always come before options. Bundle names cannot start with "-".

=head2 Extended Base Module

We can further extend our base module to create more specialized modules for
classes and testing.

    package My::Class;
    use parent 'My::Base';
    our @IMPORT_MODULES = (
        'Moo::Lax',
        'Types::Standard' => [qw( :all )],
    );

    package My::Test;
    use parent 'My::Base';
    our @IMPORT_MODULES = (
        'Test::More',
        'Test::Deep',
        'Test::Exception',
        'Test::Differences',
    );

Now all our classes just need to C<use My::Class> and all our test scripts just
need to C<use My::Test>.

B<NOTE:> Be careful when extending base modules from other projects! If the
module you are extending changes, your modules may unexpectedly break. It is
best to keep your base modules on a per-project scale.

=head2 Unimporting

Sometimes instead of C<use Module> we need to do C<no Module>, to turn off
C<strict> or C<warnings> categories for example.

By prefixing the module name with a C<->, Import::Base will act like C<no>
instead of C<use>.

    package My::Base;
    use parent 'Import::Base';
    our @IMPORT_MODULES = (
        'strict',
        'warnings',
        feature => [qw( :5.20 signatures )],
        '-warnings' => [qw( experimental::signatures )],
    );

Now the warnings for using the 5.20 subroutine signatures feature will be
disabled.

=head2 Version Check

The standard Perl C<use> function allows for a version check at compile
time to ensure that a module is at least a minimum version.

    # Require Getopt::Long version 2.31 or higher
    use Getopt::Long 2.31;

Generally, you should be declaring your dependency with the correct version,
but some modules (like Getopt::Long) change their behavior based on what
version you ask for.

To ask for a specific version, use a hashref with the key is the module and
the value as the required version.

    our @IMPORT_MODULES = (
        # Require a minimum version
        { 'Getopt::Long' => 2.31 },
        # Version and imports
        { 'File::Spec::Functions' => 3.47 } => [qw( catfile )],
    );

=head2 -exclude

When importing a base module, you can use C<-exclude> to prevent certain
modules or symbols from being imported (if, for example, they would
conflict with existing symbols).

    # Prevent the "warnings" module from being imported
    use My::Base -exclude => [ 'warnings' ];

lib/Import/Base.pm  view on Meta::CPAN

    =head1 DESCRIPTION

    This is the base module that all {{PROJECT}} files should use.

    This module always imports the following into your namespace:

    =over

    =item L<strict>

    =item L<warnings>

    =item L<feature>

    Currently the 5.20 feature bundle

    =item L<experimental> 'signatures' 'postderef'

    We are using the 5.20 experimental signatures and postfix deref syntax.

    =back

    =head1 BUNDLES

    The following bundles are available. You may import one or more of these by name.

    =head2 Class

    The class bundle makes your package into a class and includes:

    =over 4

    =item L<Moo::Lax>

    =item L<Types::Standard> ':all'

    =back

    =head2 Role

    The role bundle makes your package into a role and includes:

    =over 4

    =item L<Moo::Role::Lax>

    =item L<Types::Standard> ':all'

    =back

    =head2 Test

    The test bundle includes:

    =over 4

    =item L<Test::More>

    =item L<Test::Deep>

    =item L<Test::Differences>

    =item L<Test::Exception>

    =back

    =head1 SEE ALSO

    =over

    =item L<Import::Base>

    =back

=head1 BEST PRACTICES

=head2 One Per Project

Every project of at least medium size should have its own base module.
Consolidating a bunch of common base modules into a single distribution and
releasing to CPAN may sound like a good idea, but it opens you up to
difficult-to-diagnose problems.

If many projects all depend on the same base, any change to the central base
module could potentially break one of the consuming modules. In a single,
well-tested project, it is easy to track down and address issues due to changes
in the base module. If the base module is released to CPAN, breakage may not
appear until someone tries to install a module that depends on your base.

Version incompatibility, where project Foo depends on version 1 of the base,
while project Bar depends on version 2, will create very frustrating situations
for your users.

Having to track down another project to figure out what modules are active in
the current package is a lot of work, creating frustration for contributing
authors.

=head1 KNOWN ISSUES

=over 4

=item Moo::Role does not work if base module shares the same file as role package

When trying to import L<Moo::Role> using Import::Base, the role will not
be applied if it shares the same file as the Import::Base module. For
safety and sanity, you should keep your Import::Base module separate
from classes and roles.

=item Dancer plugins do not work when applied with Import::Base

Dancer plugins check, at compile time, to see if they can be imported into
the consuming class by looking for the Dancer DSL. Because Import::Base uses
Module::Runtime to load the class, Dancer::Plugin thinks Module::Runtime is
the calling class, sees there is no DSL to register itself with, and bails.

This issue was fixed in Dancer2 v0.200000 (released 2016-05-31). See
L<https://github.com/PerlDancer/Dancer2/pull/1136> for more information.

=back

=head1 SEE ALSO



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