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 )