1 package MooseX::ConfigFromFile;
4 use MooseX::Types::Path::Tiny 'Path';
5 use MooseX::Types::Moose 'Undef';
8 use namespace::autoclean;
10 requires 'get_config_from_file';
12 # overridable in consuming class or role to provide a default value
13 # This is called before instantiation, so it must be a class method,
14 # and not depend on any other attributes
15 sub _get_default_configfile { }
21 predicate => 'has_configfile',
22 do { try { require MooseX::Getopt; (traits => ['Getopt']) } },
24 # it sucks that we have to do this rather than using a builder, but some old code
25 # simply swaps in a new default sub into the attr definition
26 default => sub { shift->_get_default_configfile },
30 my ($class, %opts) = @_;
34 if(defined $opts{configfile}) {
35 $configfile = $opts{configfile}
38 # This would only succeed if the consumer had defined a new configfile
39 # sub to override the generated reader - as suggested in old
41 $configfile = try { $class->configfile };
43 # this is gross, but since a lot of users have swapped in their own
44 # default subs, we have to keep calling it rather than calling a
45 # builder sub directly - and it might not even be a coderef either
46 my $cfmeta = $class->meta->find_attribute_by_name('configfile');
47 $configfile = $cfmeta->default if not defined $configfile and $cfmeta->has_default;
49 if (ref $configfile eq 'CODE') {
50 $configfile = $configfile->($class);
53 my $init_arg = $cfmeta->init_arg;
54 $opts{$init_arg} = $configfile if defined $configfile and defined $init_arg;
57 if (defined $configfile) {
58 my $hash = $class->get_config_from_file($configfile);
60 no warnings 'uninitialized';
61 croak "get_config_from_file($configfile) did not return a hash (got $hash)"
62 unless ref $hash eq 'HASH';
64 %opts = (%$hash, %opts);
78 MooseX::ConfigFromFile - An abstract Moose role for setting attributes from a configfile
83 ## A real role based on this abstract role:
86 package MooseX::SomeSpecificConfigRole;
89 with 'MooseX::ConfigFromFile';
91 use Some::ConfigFile::Loader ();
93 sub get_config_from_file {
94 my ($class, $file) = @_;
96 my $options_hashref = Some::ConfigFile::Loader->load($file);
98 return $options_hashref;
103 ## A class that uses it:
107 with 'MooseX::SomeSpecificConfigRole';
109 # optionally, default the configfile:
110 sub _get_default_configfile { '/tmp/foo.yaml' }
112 # ... insert your stuff here ...
115 ## A script that uses the class with a configfile
118 my $obj = Foo->new_with_config(configfile => '/etc/foo.yaml', other_opt => 'foo');
122 This is an abstract role which provides an alternate constructor for creating
123 objects using parameters passed in from a configuration file. The
124 actual implementation of reading the configuration file is left to
127 It declares an attribute C<configfile> and a class method C<new_with_config>,
128 and requires that concrete roles derived from it implement the class method
129 C<get_config_from_file>.
131 Attributes specified directly as arguments to C<new_with_config> supersede those
134 L<MooseX::Getopt> knows about this abstract role, and will use it if available
135 to load attributes from the file specified by the command line flag C<--configfile>
136 during its normal C<new_with_options>.
142 This is a L<Path::Tiny> object which can be coerced from a regular path
143 string or any object that supports stringification.
144 This is the file your attributes are loaded from. You can add a default
145 configfile in the consuming class and it will be honored at the appropriate
146 time; see below at L</_get_default_configfile>.
148 If you have L<MooseX::Getopt> installed, this attribute will also have the
149 C<Getopt> trait supplied, so you can also set the configfile from the
154 =head2 new_with_config
156 This is an alternate constructor, which knows to look for the C<configfile> option
157 in its arguments and use that to set attributes. It is much like L<MooseX::Getopts>'s
158 C<new_with_options>. Example:
160 my $foo = SomeClass->new_with_config(configfile => '/etc/foo.yaml');
162 Explicit arguments will override anything set by the configfile.
164 =head2 get_config_from_file
166 This class method is not implemented in this role, but it is required of all
167 classes or roles that consume this role.
168 Its two arguments are the class name and the configfile, and it is expected to return
169 a hashref of arguments to pass to C<new()> which are sourced from the configfile.
171 =head2 _get_default_configfile
173 This class method returns nothing by default, but can and should be redefined
174 in a consuming class to return the default value of the configfile (if not
175 passed into the constructor explicitly).
179 Copyright (c) - the MooseX::ConfigFromFile "AUTHOR" and "CONTRIBUTORS" as listed below.
183 Brandon L. Black, E<lt>blblack@gmail.comE<gt>
191 =item Karen Etheridge
195 =item Zbigniew Lukasiak
201 This library is free software; you can redistribute it and/or modify
202 it under the same terms as Perl itself.