Fixed docs to show how to override configfile. Also tests!
Karen Etheridge [Sun, 3 Feb 2013 01:09:47 +0000 (17:09 -0800)]
Note that the configfile sub might be called more than once, as the value is
effectively not cached at all in the attribute. However this is not likely to
be a big deal (I am assuming). :)

ChangeLog
lib/MooseX/ConfigFromFile.pm
t/05_default_sub.t [new file with mode: 0644]

index 9fc11cf..c145019 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 Revision history for Perl extension MooseX::ConfigFromFile
 
+0.05
+    - documentation corrected to demostrate how to properly override the
+    configfile method to provide a default from the consuming class, without
+    having to redefine the attribute itself
+
 0.04 - Dec 17, 2011
     - Call the configfile attribute default sub if it is a sub, not just a
       string, just like MooseX::Getopt does (RT#73325, Karen Etheridge)
index a2d2211..2de2688 100644 (file)
@@ -26,9 +26,16 @@ sub new_with_config {
         $configfile = $opts{configfile}
     }
     else {
-        my $cfmeta = $class->meta->find_attribute_by_name('configfile');
+        # This would only succeed if the consumer had defined a new configfile
+        # sub to override the generated reader
         $configfile = try { $class->configfile };
+
+        # this is gross, but since a lot of users have swapped in their own
+        # default subs, we have to keep calling it rather than calling a
+        # builder sub directly - and it might not even be a coderef either
+        my $cfmeta = $class->meta->find_attribute_by_name('configfile');
         $configfile ||= $cfmeta->default if $cfmeta->has_default;
+
         if (ref $configfile eq 'CODE') {
             $configfile = $configfile->($class);
         }
@@ -87,7 +94,7 @@ MooseX::ConfigFromFile - An abstract Moose role for setting attributes from a co
   with 'MooseX::SomeSpecificConfigRole';
 
   # optionally, default the configfile:
-  sub configfile { '/tmp/foo.yaml' }
+  around configfile => sub { '/tmp/foo.yaml' };
 
   # ... insert your stuff here ...
 
@@ -121,9 +128,11 @@ during its normal C<new_with_options>.
 
 This is a L<Path::Class::File> object which can be coerced from a regular pathname
 string.  This is the file your attributes are loaded from.  You can add a default
-configfile in the class using the role and it will be honored at the appropriate time:
+configfile in the consuming class and it will be honored at the appropriate time
+(note that a simple sub declaration is not sufficient, as there is already a
+sub by that name being added by Moose as the attribute reader)
 
-  has +configfile ( default => '/etc/myapp.yaml' );
+  around configfile => sub { '/etc/myapp.yaml' };
 
 Note that you can alternately just provide a C<configfile> method which returns
 the config file when called - this will be used in preference to the default of
diff --git a/t/05_default_sub.t b/t/05_default_sub.t
new file mode 100644 (file)
index 0000000..122c263
--- /dev/null
@@ -0,0 +1,89 @@
+use strict;
+use warnings;
+
+use Test::More tests => 10;
+use Test::Fatal;
+use Test::Deep '!blessed';
+use Test::NoWarnings 1.04 ':early';
+use Scalar::Util 'blessed';
+
+my %loaded_file;
+my %default_sub;
+
+
+# nothing special going on here
+{
+    package Generic;
+    use Moose;
+    with 'MooseX::SimpleConfig';
+    sub get_config_from_file { }
+}
+
+is(
+    exception {
+        my $obj = Generic->new_with_config;
+        is($obj->configfile, undef, 'no configfile set');
+    },
+    undef,
+    'no exceptions',
+);
+
+
+# this is a classic legacy usecase from old documentation that we must
+# continue to support
+{
+    package OverriddenDefault;
+    use Moose;
+    with 'MooseX::SimpleConfig';
+    sub get_config_from_file
+    {
+        my ($class, $file) = @_;
+        $loaded_file{$file}++;
+        +{}
+    }
+    has '+configfile' => (
+        default => 'OverriddenDefault file',
+    );
+}
+
+is(
+    exception {
+        my $obj = OverriddenDefault->new_with_config;
+        is($obj->configfile, blessed($obj) . ' file', 'configfile set via overridden default');
+        is($loaded_file{blessed($obj) . ' file'}, 1, 'correct file was loaded from');
+    },
+    undef,
+    'no exceptions',
+);
+
+
+# "reader" method is overridden to provide for configfile default
+{
+    package OverriddenMethod;
+    use Moose;
+    with 'MooseX::SimpleConfig';
+    sub get_config_from_file {
+        my ($class, $file) = @_;
+        $loaded_file{$file}++;
+        +{}
+    }
+
+    around configfile => sub {
+        my $class = blessed($_[1]) || $_[1];
+        $default_sub{$class}++;
+        $class . ' file'
+    };
+}
+
+is(
+    exception {
+        my $obj = OverriddenMethod->new_with_config;
+        is($obj->configfile, blessed($obj) . ' file', 'configfile set via overridden sub');
+        ok($default_sub{blessed($obj)}, 'default sub was called');
+        is($loaded_file{blessed($obj) . ' file'}, 1, 'correct file was loaded from');
+    },
+    undef,
+    'no exceptions',
+);
+
+