
Config::PCF - Perl Config Format

use Config::PCF;
use Data::Dumper;
my $config = Config::PCF->parse_scalar(<<CONFIG);
%% #information
This is a perlish config file.
%% &date
# This gets interpolated into an anonymous subroutine
use POSIX qw(strftime);
return strftime('%Y%m%d', localtime);
%% $template
[%# a plain scalar #%]
Created on [% date %]
%% %defaults
foo: bar
baz: glonk
CONFIG
print Dumper $config;
__END__
# Output:
parse_file FILENAMEReads in a file.
Returns a hash reference to the sections.
Config::PCF->parse_scalar SCALARParses the configuration information from a scalar.
Returns a hash reference to the sections.

The configuration syntax is simple:
Every section is indicated by two leading percent signs:
%% $template ... %% @urls ... %% #@old_urls ...
The name of every section is prefixed by a sigil. The sigils have the following meanings:
$ - scalar
Turns the section into a plain scalar
%% $template Your search gave the following results: [% FOR r IN results %] * [% r.description %] - [% r.url %] [% END %] Thanks and come again.
becomes
{
template = 'Your search gave the following results:
[% FOR r IN results %]
* [% r.description %] - [% r.url %]
[% END %]
Thanks and come again.',
}
@ - list
All lines will be chomped and turned into an array reference. Thus
%% @search_engines http://google.com/q=%s http://search.yahoo.com/search?p=%s
becomes
{ search_engines => [
'http://google.com/q=%s',
'http://search.yahoo.com/search?p=%s',
]
}
% - hash
A simple, flat list of colon-separated items will be turned into a hash reference:
%% %homepages Corion: http://corion.net Perl: http://perl.org
becomes
{ homepages => {
Corion => 'http://corion.net',
Perl => 'http://perl.org',
}
}
& - anonymous subroutine
The given Perl code gets interpolated into an anonymous subroutine.
%% ×tamp
use POSIX;
return strftime '%Y%m%d', localtime
becomes
{ timestamp => sub {
use POSIX;
return strftime '%Y%m%d', localtime
}
}
! - immediate execution
Like the anonymous subroutine, the code gets interpolated into a code block. That code block gets executed immediately getting the section name as parameter.
Whatever the code block returns will be put in the config slot.
%% !debug
print "I am here.";
return [
'http://google.com',
];
# - comment
A comment section will not show up in the configuration hash. If you want a comment section that shows up, just use a scalar section.
%% #information This is some comment.

Here are some syntax enhancements that might be useful some day but which I haven't felt the need to implement yet:
<> - include file
This would include a file as a whole, pulling in the sections of that file, possibly overwriting sections in the current file.
The following would first load all default configurations, then overwrite parts of them with custom configurations:
%% <default/*.pcf> %% <custom/*.pcf>
< - read section from file
This would read the value of a specific section from a file (or, maybe even weirder, in IO::All-style, from anywhere, opening up big security holes).
%% $template <root/index.tt
This would read the value for the template entry in the configuration from the file root/index.tt.
Whether that idea is better than doing this in your program remains up to debate.
By IO::All-style I mean allowing processes or URLs to be specified as well:
%% $slashdot <http://rss.slashdot.org/Slashdot/slashdot
But the utility of that is even more limited as you'll likely be writing your own reader/parser and thus could just use the list of URLs and fetch them yourself, preferrably with some caching anyway.
<< - append to section from file
This will append to the section from a file.
%% @urls http://google.com http://search.yahoo.com %% @urls <<pending-urls.lst %% @urls <<new-urls.lst