Skip to content

Instantly share code, notes, and snippets.

@markstos
Created November 16, 2012 16:51
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save markstos/4088910 to your computer and use it in GitHub Desktop.
Design attempt for a Moose role to provide access to a singleton config object
package Project::Role::Config;
use Moose::Role;
use Project::ConfigSingleton;
use Project::ToolSet;
Project::ConfigSingleton->initialize;
# The config hash provided by this role is managed by a singleton class
has 'config_singleton' => (
lazy => 1,
isa => 'Project::ConfigSingleton',
is => 'ro',
default => sub { Project::ConfigSingleton->instance },
);
=head1 ATTRIBUTES
=head2 config_singleton
=head1 METHODS
=head2 cfg()
# Access a config hash key directly
$self->cfg('FIELD');
# Return config as hash
my %CFG = $self->cfg;
# return as hashref
my $cfg_href = $self->cfg;
A method to access project configuration variables. The config
file is parsed on the first call with a perl hash representation stored in memory.
Subsequent calls will use this version, rather than re-reading the file.
In list context, it returns the configuration data as a hash.
In scalar context, it returns the configuration data as a hashref.
=cut
sub cfg {
my $self = shift;
my $field = shift;
my $cfg = $self->config_singleton->config;
assert( exists( $cfg->{$field} ), "There is a config variable names '$field'" );
return $cfg->{$field} if $field;
return wantarray ? %$cfg : $cfg;
}
##############################################################
package Project::ConfigSingleton;
use MooseX::Singleton;
use Dir::Self;
has config_files => (
lazy => 1,
is => 'ro',
isa => 'ArrayRef[Str]',
default => sub { [ __DIR__ . '/../../config/Config.pl' ] },
);
has 'config' => (
is => 'rw',
isa => 'HashRef',
init_arg => undef,
);
sub BUILD {
my $self = shift;
# Read in config files in the order the appear in this array.
my %combined_cfg;
my $files_aref = $self->config_files;
for (my $i = 0; $i < scalar @$files_aref; $i++) {
my $file = $files_aref->[$i];
my %parms;
if (ref $files_aref->[$i+1] eq 'HASH') {
%parms = %{ $files_aref->[$i+1] };
# skip trying to process the hashref as a file name
$i++;
}
my $cfg = do $file;
warn "couldn't parse $file: $@" if $@;
warn "couldn't do $file: $!" unless defined $cfg;
warn "$file didn't return a hashref" unless ref $cfg eq 'HASH';
%combined_cfg = (%combined_cfg, %$cfg);
}
die "No configuration found. Check your config file(s) including their syntax." unless keys %combined_cfg;
$self->config(\%combined_cfg);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment