Implementing the Toggle Function in Perl5
I would like to be able to create packages "ghost" and subtitles. I have a config file (ini) with items like this:
[features]
sys.ext.latex = off
gui.super.duper.elastic = off
user.login.rsa = on
This file is parsed and later, developers can ask questions such as:
if ( MyApp::Feature->enabled ( 'user.login.rsa' ) { ... }
(The whole idea is based on Martin Fowler FeatureToggle http://martinfowler.com/bliki/FeatureToggle.html )
Using AUTOLOAD to look up calls in MyApp :: Feature and a BEGIN block to parse the ini file, we can provide this API:
if ( MyApp::Feature->user_login_rsa ) { ... }
Question: is it possible to create the following API:
if ( MyApp::Feature::User::Login::RSA ) { ... }
only has MyApp :: Feature?
Below, upper case can be changed in the config file, this is not a problem. And it's clear that implementation is separate from configuration, there is no MyApp :: Feature :: User :: Login :: RSA and never will be. The implementation of this feature is that fe in MyApp :: People.
I am aware that including MyApp :: Feature :: Foo :: Bar presupposes such a package. But developers know the convention that the Feature package manages feature switching, and they would have no problem with that. I find the first example (using the enabled ($ string) bit too tricky to read
if ( package::package->method ( string ) )
the second is better:
if ( package::package->method )
the third will be even easier:
if ( package::package::package )
So, can AUTOLOAD be simulated at the package level?
Hi Rob.
source to share
So it looks like you have a list of verbose keys that you want to set to the namespace.
BEGIN {
my %states = ( # the values that should be transformed
on => sub () {1},
off => sub () {''},
);
sub install_config {
my ($package, $config) = @_;
for my $key (keys %$config) {
my @parts = map ucfirst, split /\./, $key;
my $name = join '::' => $package, @parts;
no strict 'refs';
*{$name} = $states{$$config{$key}} # use a tranformed value
|| sub () {$$config{$key}} # or the value itself
}
}
}
BEGIN {
my %config = qw(
sys.ext.latex off
gui.super.duper.elastic off
user.login.rsa on
some.other.config other_value
);
install_config 'MyApp::Feature' => \%config;
}
say MyApp::Feature::Sys::Ext::Latex ? 'ON' : 'OFF'; # OFF
say MyApp::Feature::Gui::Super::Duper::Elastic ? 'ON' : 'OFF'; # OFF
say MyApp::Feature::User::Login::Rsa ? 'ON' : 'OFF'; # ON
say MyApp::Feature::Some::Other::Config; # other_value
The persistent routines set here will be bound by perl when applicable.
You can make it a install_config
little easier to use by putting it in the package import function:
BEGIN {$INC{'Install/Config.pm'}++} # fool require
sub Install::Config::import {shift; goto &install_config}
use Install::Config 'MyApp::Feature' => {qw(
sys.ext.latex off
gui.super.duper.elastic off
user.login.rsa on
some.other.config other_value
)};
source to share