@@ -1,5 +1,11 @@
Revision history for MooX-ConfigFromFile
+0.004 2014-10-28
+ - add ability for options to importer of MooX::ConfigFromFile
+ - add option to have a singleton config (loaded once).
+ - improve documentation
+ - harmonize tests
+
0.003 2014-08-02
- fix links in documentation to fix RT#97429 (thanks abraxxa for
reporting)
@@ -7,7 +7,8 @@ MANIFEST
MANIFEST.SKIP
README.md
t/00-load.t
-t/01-parse.t
+t/01-moo.t
t/02-moose.t
+t/testlib.pm
META.yml Module YAML meta-data (added by MakeMaker)
META.json Module JSON meta-data (added by MakeMaker)
@@ -4,7 +4,7 @@
"Jens Rehsack <rehsack@cpan.org>"
],
"dynamic_config" : 1,
- "generated_by" : "ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.141520",
+ "generated_by" : "ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.142060",
"license" : [
"perl_5"
],
@@ -65,5 +65,5 @@
"http://dev.perl.org/licenses/"
]
},
- "version" : "0.003"
+ "version" : "0.004"
}
@@ -11,7 +11,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.141520'
+generated_by: 'ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.142060'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -30,4 +30,4 @@ requires:
perl: v5.8.1
resources:
license: http://dev.perl.org/licenses/
-version: '0.003'
+version: '0.004'
@@ -3,7 +3,7 @@ package MooX::ConfigFromFile::Role;
use strict;
use warnings;
-our $VERSION = '0.003';
+our $VERSION = '0.004';
use Moo::Role;
@@ -41,17 +41,22 @@ has 'config_prefix' => ( is => 'lazy' );
sub _build_config_prefix { $Script; }
+has 'config_extensions' => ( is => 'lazy' );
+
+sub _build_config_extensions { [ Config::Any->extensions() ] }
+
has 'config_files' => ( is => 'lazy' );
sub _build_config_files
{
my ( $class, $params ) = @_;
- defined $params->{config_prefix} or $params->{config_prefix} = $class->_build_config_prefix($params);
- defined $params->{config_dirs} or $params->{config_dirs} = $class->_build_config_dirs($params);
+ defined $params->{config_prefix} or $params->{config_prefix} = $class->_build_config_prefix($params);
+ defined $params->{config_dirs} or $params->{config_dirs} = $class->_build_config_dirs($params);
+ defined $params->{config_extensions} or $params->{config_extensions} = $class->_build_config_extensions($params);
ref $params->{config_dirs} eq "ARRAY" or $params->{config_dirs} = ["."];
- my @cfg_pattern = map { $params->{config_prefix} . "." . $_ } Config::Any->extensions();
+ my @cfg_pattern = map { $params->{config_prefix} . "." . $_ } @{ $params->{config_extensions} };
my @cfg_files = File::Find::Rule->file()->name(@cfg_pattern)->maxdepth(1)->in( @{ $params->{config_dirs} } );
return \@cfg_files;
@@ -103,6 +108,13 @@ already in C<$params>.
This role uses following attributes which might be suitable customized by
overloading the appropriate builder or pass defaults in construction arguments.
+Be sure to read L<MooX::File::ConfigDir/ATTRIBUTES>, especially
+L<MooX::File::ConfigDir/config_identifier> to understand how the L</config_dirs>
+are build.
+
+When you miss a directory - see L<File::ConfigDir/plug_dir_source> and
+L<File::ConfigDir::Plack>.
+
=head2 config_prefix
This attribute defaults to L<FindBin>'s C<$Script>. It's interpreted as the
@@ -110,14 +122,17 @@ basename of the config file name to use.
=head2 config_dirs
-This attribute is included from L<MooX::File::ConfigDir|MooX::File::ConfigDir/config_dirs>.
-It might be unclever to override - but possible. Use with caution.
+This attribute is consumed from L<MooX::File::ConfigDir|MooX::File::ConfigDir/config_dirs>.
+It might not be smart to override - but possible. Use with caution.
+
+=head2 config_extensions
+
+This attribute defaults to list of extensions from L<Config::Any|Config::Any/extensions>.
=head2 config_files
This attribute contains the list of existing files in I<config_dirs> matching
-I<config_prefix> . L<Config::Any-E<gt>extensions|Config::Any/extensions>.
-Search is operated by L<File::Find::Rule>.
+I<config_prefix> . I<config_extensions>. Search is operated by L<File::Find::Rule>.
=head1 AUTHOR
@@ -3,11 +3,13 @@ package MooX::ConfigFromFile;
use strict;
use warnings FATAL => 'all';
-our $VERSION = '0.003';
+our $VERSION = '0.004';
+
+my %loaded_configs;
sub import
{
- my ( undef, @import ) = @_;
+ my ( undef, %import_options ) = @_;
my $target = caller;
my @target_isa;
{ no strict 'refs'; @target_isa = @{"${target}::ISA"} };
@@ -24,6 +26,35 @@ sub import
};
$apply_modifiers->();
+ my $around;
+ defined $import_options{config_singleton} and $import_options{config_singleton} and do
+ {
+ $around or $around = $target->can('around');
+ $around->(
+ _build_loaded_config => sub {
+ my $orig = shift;
+ my $self = shift;
+ my $class = ref $self ? ref $self : $self;
+ defined $loaded_configs{$class} or $loaded_configs{$class} = $self->$orig(@_);
+ return $loaded_configs{$class};
+ }
+ );
+ };
+
+ my %default_modifiers = (
+ config_prefix => '_build_config_prefix',
+ config_extensions => '_build_config_extensions',
+ config_dirs => '_build_config_dirs',
+ config_files => '_build_config_files',
+ );
+
+ foreach my $opt_key ( keys %default_modifiers )
+ {
+ exists $import_options{$opt_key} or next;
+ $around or $around = $target->can('around');
+ $around->( $default_modifiers{$opt_key} => sub { $import_options{$opt_key} } );
+ }
+
return;
}
@@ -68,7 +99,8 @@ MooX::ConfigFromFile - Moo eXtension for initializing objects from config file
use Moo;
- use MooX::ConfigFromFile; # imports the MooX::ConfigFromFile::Role
+ # consumes the MooX::ConfigFromFile::Role but load config only once
+ use MooX::ConfigFromFile config_singleton => 1;
with "Role::Action";
@@ -93,6 +125,41 @@ on object construction from an appropriate config file. The building is
done in L<MooX::ConfigFromFile::Role> - using MooX::ConfigFromFile ensures
the role is applied.
+For easier usage, with 0.004, several options can be passed via I<use> resulting
+in default initializers for appropriate role attributes:
+
+=over 4
+
+=item C<config_prefix>
+
+Default for L<MooX::ConfigFromFile::Role/config_prefix>.
+
+=item C<config_extensions>
+
+Default for L<MooX::ConfigFromFile::Role/config_extensions>.
+
+=item C<config_dirs>
+
+Default for L<MooX::ConfigFromFile::Role/config_dirs>.
+Same warning regarding modifying this attribute applies here:
+Possible, but use with caution!
+
+=item C<config_files>
+
+Default for L<MooX::ConfigFromFile::Role/config_files>.
+
+Reasonable when you want exactly one config file in development mode.
+For production code it is highly recommended to override the builder.
+
+=item C<config_singleton>
+
+Flag adding a wrapper L<< around|Class::Method::Modifiers/around method(s) => sub { ... }; >>
+the I<builder> of L<MooX::ConfigFromFile::Role/loaded_config> to ensure a
+config is loaded only once per class. The I<per class> restriction results
+from applicable modifiers per class (and singletons are per class).
+
+=back
+
=head1 AUTHOR
Jens Rehsack, C<< <rehsack at cpan.org> >>
@@ -133,10 +200,8 @@ L<http://search.cpan.org/dist/MooX-ConfigFromFile/>
=back
-
=head1 ACKNOWLEDGEMENTS
-
=head1 LICENSE AND COPYRIGHT
Copyright 2013-2014 Jens Rehsack.
@@ -0,0 +1,12 @@
+#!perl
+
+use 5.008003;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Test::More;
+
+do "t/testlib.pm";
+
+done_testing;
@@ -1,49 +0,0 @@
-#!perl
-
-use 5.008003;
-
-use strict;
-use warnings FATAL => 'all';
-
-use Test::More;
-
-my $dist_basedir =
- Cwd::abs_path( File::Spec->catdir( File::Basename::dirname($0), File::Spec->updir() ) );
-
-{
- package #
- Calc::Role::BinaryOperation;
- use Moo::Role;
-
- has a => (
- is => 'ro',
- required => 1,
- );
-
- has b => (
- is => 'ro',
- required => 1,
- );
-}
-
-
-{
- package #
- Calc::add;
- use Moo;
- use MooX::ConfigFromFile;
-
- with 'Calc::Role::BinaryOperation';
-
- sub execute {
- my $self = shift;
- return $self->a + $self->b;
- }
-}
-
-my $adder = Calc::add->new( config_prefix => 'calc-operands' );
-ok(defined($adder->a), "read 'a' from config");
-ok(defined($adder->b), "read 'b' from config");
-cmp_ok($adder->execute, "==", 5, "read right adder config");
-
-done_testing;
@@ -12,43 +12,6 @@ BEGIN {
$@ and plan skip_all => "Moose test requires Moose being installed";
}
-my $dist_basedir =
- Cwd::abs_path( File::Spec->catdir( File::Basename::dirname($0), File::Spec->updir() ) );
-
-{
- package #
- Calc::Role::BinaryOperation;
- use Moose::Role;
-
- has a => (
- is => 'ro',
- required => 1,
- );
-
- has b => (
- is => 'ro',
- required => 1,
- );
-}
-
-
-{
- package #
- Calc::add;
- use Moose;
- use MooX::ConfigFromFile;
-
- with 'Calc::Role::BinaryOperation';
-
- sub execute {
- my $self = shift;
- return $self->a + $self->b;
- }
-}
-
-my $adder = Calc::add->new( config_prefix => 'calc-operands' );
-ok(defined($adder->a), "read 'a' from config");
-ok(defined($adder->b), "read 'b' from config");
-cmp_ok($adder->execute, "==", 5, "read right adder config");
+do "t/testlib.pm";
done_testing;
@@ -0,0 +1,86 @@
+use strict;
+use warnings FATAL => 'all';
+
+{
+ package #
+ Calc::Role::BinaryOperation;
+ use Moo::Role;
+
+ has a => (
+ is => 'ro',
+ required => 1,
+ );
+
+ has b => (
+ is => 'ro',
+ required => 1,
+ );
+}
+
+{
+ package #
+ Calc::add;
+ use Moo;
+ use MooX::ConfigFromFile;
+
+ with 'Calc::Role::BinaryOperation';
+
+ sub execute
+ {
+ my $self = shift;
+ return $self->a + $self->b;
+ }
+}
+
+{
+ package #
+ Calc::sub;
+ use Moo;
+ use MooX::ConfigFromFile config_prefix => 'calc-operands';
+
+ with 'Calc::Role::BinaryOperation';
+
+ sub execute
+ {
+ my $self = shift;
+ return $self->a - $self->b;
+ }
+}
+
+{
+ package #
+ Calc::mul;
+ use Moo;
+ use MooX::ConfigFromFile
+ config_prefix => 'calc-operands',
+ config_singleton => 1;
+
+ with 'Calc::Role::BinaryOperation';
+
+ sub execute
+ {
+ my $self = shift;
+ return $self->a * $self->b;
+ }
+}
+
+my $adder = Calc::add->new( config_prefix => 'calc-operands' );
+ok( defined( $adder->a ), "read 'a' from add config" );
+ok( defined( $adder->b ), "read 'b' from add config" );
+cmp_ok( $adder->execute, "==", 5, "read right adder config" );
+
+my $subber = Calc::sub->new;
+ok( defined( $subber->a ), "read 'a' from sub config" );
+ok( defined( $subber->b ), "read 'b' from sub config" );
+cmp_ok( $subber->execute, "==", -1, "read right subber config" );
+
+my $mul1 = Calc::mul->new;
+ok( defined( $mul1->a ), "read 'a' from mul1 config" );
+ok( defined( $mul1->b ), "read 'b' from mul1 config" );
+cmp_ok( $mul1->execute, "==", 6, "read right mul config" );
+
+my $mul2 = Calc::mul->new( config_prefix => 'no-calc-operands' );
+ok( defined( $mul2->a ), "copy 'a' from mul1 config" );
+ok( defined( $mul2->b ), "copy 'b' from mul1 config" );
+cmp_ok( $mul2->execute, "==", 6, "right mul1 config duplicated" );
+