Intro
This node is a follow up to my original post on creating Object Oriented Configuration Values. Rather then repeat some of information from that node here, I recommend you read it first if you haven't already. After reading the replies and getting more exposure to various techniques I realized my original approach had some flaws. The intent of this node is to offer a refined approach that is more flexible and removes some potential bottlenecks.
New Information
blokhead had an issue with the fact that each call to new would recreate the methods, this is some expensive overhead since each method is dynamically created. A better way to do this would be create the methods at compile time and simply keep them available in their own class.
My::Config
In the last version we used OurApp::Base , but for this one we move into a slightly modified format. In the initial version each application level call to the module required us to pass in configuration files options, we can do away with that. By creating two slightly more robust core modules we can provide additional flexibility and reduce our per application code. Here is one of our new classes.
package My::Config;
use strict;
use base ( 'Class::Accessor' );
use Config::Auto;
my $base = __PACKAGE__;
our $config_hash = {};
bless $config_hash , $base;
my $config = Config::Auto::parse( '/home/trs80/my.conf',
format => 'equal' );
$base->mk_accessors(keys %{$config});
foreach (keys %{$config}) {
$config_hash->$_($config->{$_});
}
sub new {
return $config_hash;
}
1;
It now holds all the information about where to find the configuration files and it only loads the data once and then simply passes the object containing our values out when new is called. This reduces our overhead tremendously since we aren't auto generating methods on every call to My::Config->new(). Which is good in a persistent environment.
Our New Base Class
We have to create a new base class to address our changes to our configuration data. Here is our revised Base module.
package My::Base;
use My::Config;
sub new {
my $self = { };
bless $self , 'My::Base';
}
sub config {
my ($self) = @_;
my $config = My::Config->new();
return $config;
}
sub AUTOLOAD {
my ( $self, $value ) = @_;
$AUTOLOAD =~ /.*::(\w+)/;
my $command = $1;
if ( defined($value) ) {
$self->config->$command($value);
return;
} else {
return $self->config->$command;
}
}
1;
Three Ways to Get What You Want
In the initial version both IlyaM and Ctrl-z expressed some concern with the interface to the configuration values. In this version we modify this access to allow for the initial method along with two new ways.
Our three ways to access it are:
- As a My::Config object
- As a part of a config method provided by My::Base
- As a method name of the My::Base object generated by the AUTOLOAD
Here are the three tests:
!/usr/bin/perl
# access config data directly from the My::Config class
use My::Config;
use strict;
my $config = My::Config->new();
print $config->base_directory , "\n";
$config->base_directory("/home/otheruser/");
print $config->base_directory() , "\n";
#!/usr/bin/perl
# access configuration data through the My::Base class
use My::Base;
use strict;
my $object = My::Base->new();
print $object->config->base_directory , "\n";
$object->config->base_directory("/home/otheruser/");
print $object->config->base_directory() , "\n";
#!/usr/bin/perl
use My::Base;
use strict;
# access configuration data by name through AUTOLOAD
my $object = My::Base->new();
print $object->base_directory , "\n";
$object->base_directory("/home/otheruser/");
print $object->base_directory() , "\n";
Conclusion
The revised way of providing OO oriented access to configuration data improves upon the initial design by further reducing the application level code and providing additional ways to access the information.
Edit by tye, add READMORE
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
|
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.
|
|