Code-Style-Kit

 view release on metacpan or  search on metacpan

lib/Code/Style/Kit.pm  view on Meta::CPAN

sub _default_features {
    my ($class, $parent_stashes) = @_;

    my @features;
    # loop over the parts in @ISA order
    for my $parent_stash (@{$parent_stashes}) {
        my @subs = $parent_stash->list_all_symbols('CODE');
        for my $sub (@subs) {
            # we only care about sub names of this form
            next unless $sub =~ /^feature_(\w+)_default$/;

            my $feature = $1;
            my $is_default = $class->$sub;

            if (DEBUG) {
                my $parent_class = $parent_stash->name;
                print STDERR "$class - $parent_class provides $feature, by default ",
                    ($is_default ? 'enabled' : 'disabled' ),
                    "\n";
            }

            push @features, $feature if $is_default;
        }
    }

    return @features;
}

sub _get_parent_stashes {
    my ($class) = @_;

    $class = ref($class) || $class;
    return [ map { Package::Stash->new($_) } @{ mro::get_linear_isa($class) } ];
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Code::Style::Kit - build composable bulk exporters

=head1 VERSION

version 1.0.3

=head1 SYNOPSIS

To build a "part":

      package My::Kit::Part;
      use strict;
      use warnings;

      sub feature_trytiny_default { 1 }
      sub feature_trytiny_export_list { 'Try::Tiny' }

      1;

To build the kit:

      package My::Kit;
      use parent qw(Code::Style::Kit My::Kit::Part My::Kit::OtherPart);
      1;

To use the kit:

    package My::App;
    use My::Kit;

    # you now have Try::Tiny imported, plus whatever OtherPart did

=head1 DESCRIPTION

This package simplifies writing "code style kits". A kit (also known
as a "policy") is a module that encapsulates the common pragmas and
modules that every package in a project should use. For instance, it
might be a good idea to always C<use strict>, enable method
signatures, and C<use true>, but it's cumbersome to put that
boilerplate in every single file in your project. Now you can do that
with a single line of code.

C<Code::Style::Kit> is I<not> to be C<use>d directly: you must write a
package that inherits from it. Your package can (and probably should)
also inherit from one or more "parts". See L<<
C<Code::Style::Kit::Parts> >> for information about the parts included
in this distribution.

I<Please> don't use this for libraries you intend to distribute on
CPAN: you'd be forcing a bunch of dependencies on every user. These
kits are intended for applications, or "internal" libraries that don't
get released publicly.

=head2 Features

A kit provides a set of "features" (like "tags" in L<< C<Exporter> >>
or "groups" in L<< C<Sub::Exporter> >>). Feature names must match
C<^\w+$>. Some features may be exported by default.

A simple example of a feature, from the synopsis:

    sub feature_trytiny_default { 1 }
    sub feature_trytiny_export_list { 'Try::Tiny' }

or, equivalently:

    sub feature_trytiny_default { 1 }
    sub feature_trytiny_export {
        my ($self, $caller) = @_;
        require Try::Tiny;
        Try::Tiny->import::into($caller);
    }

The C<feature_*_default> method says that this feature should always
be exported (unless the user explicitly asks us not to). The
C<feature_*_export_list> is a shortcut for the simple case of
re-exporting one or more entire packages. Alternatively, the
C<feature_*_export> sub provides full flexibility, when you need it.

=head2 Feature ordering

Sometimes you need features to be exported in a certain order:

      package My::Kit;
      use parent qw(Code::Style::Kit Code::Style::Kit::Parts::Common);

      sub feature_class_export_list { 'Moo' }
      sub feature_class_order { 200 }

      sub feature_singleton_export {
          require Role::Tiny;
          Role::Tiny->apply_roles_to_package($_[1], 'MooX::Singleton');
      }
      sub feature_singleton_order { 210 }

If someone says either:

    package My::Class;
    use My::Kit 'class', 'singleton';

or:

    package My::Class;
    use My::Kit 'singleton', 'class';

then C<Moo> will be imported first, then C<MooX::Singleton> will be
applied.

All features that don't have a C<feature_*_order> sub are assumed to
have order 100.

=head2 Dependencies

Sometimes you want to make sure that a certain feature is exported
whenever another one is.

      sub feature_class_export_list { 'Moo' }

      sub feature_singleton_export {
          my ($self, $caller) = @_;
          $self->also_export('class');
          require Role::Tiny;
          Role::Tiny->apply_roles_to_package($caller, 'MooX::Singleton');
      }

Now:

    package My::Class;
    use My::Kit 'singleton';

will work. Notice that you don't have to worry whether the feature was



( run in 2.218 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )