NAME
Config::Natural - Module that can read easy-to-use configuration files
VERSION
Version 1.01
SYNOPSIS
Lets say you have a file mail.conf
name = John Doe
email = jdoe@somewhere.net
server = mail.somewhere.net
signature = -
John Doe
--
Visit my homepage at http://www.somewhere.net/~jdoe/
.
You can read it using the following program:
use Config::Natural;
my $mailconf = new Config::Natural 'mail.conf';
and you can for example print the signature:
print $mailconf->param('signature');
DESCRIPTION
This module has been written in order to provide an easy way to read simple configuration files. The syntax of these configuration files is what seemed to me the most natural way to write these files, hence the name of this module.
One of the reason I wrote this module is that I wanted a very easy way to feed data to HTML::Template
based scripts. Therefore the API of Config::Natural
is compatible with HTML::Template
, and you can write programs as simple as:
use strict;
use Config::Natural;
use HTML::Template;
my $source = new Config::Natural 'file.src';
my $tmpl = new HTML::Template type => 'filename',
source => 'file.tmpl', associate => $source;
print $tmpl->output;
And this is not just another trivial example: I use scripts nearly as simple as this one to create most of my web pages.
SYNTAX
In brief, Config::Natural
supports the following features in configuration files:
multiline values,
arrays,
nested lists,
inclusion.
Any element of the syntax can be changed via the corresponding accessor.
Affectations
To affect a value to a parameter, simply write:
greetings = hello world
The parameter greetings
will have the value "hello world"
. You can also give multi-lines values this way:
text = -
Perl is a language optimized for scanning arbitrary text files,
extracting information from those text files, and printing
reports based on that information. It's also a good language
for many system management tasks. The language is intended to
be practical (easy to use, efficient, complete) rather than
beautiful (tiny, elegant, minimal).
[from perl(1)]
.
Think of this as a "Unix inspired" syntax. Instead of giving the value, you write "-"
to mean "the value will follow" (in Unix, this means the data will come from standard input). To end the multi-lines value, put a single dot "."
on a line (as in Unix mail, but it needn't be on the first column).
Since version 1.00, values can also be appended by prefixing the append symbol, by default +
, so if you write
motto = Everything that has a beginning
motto += has an end
the parameter motto
will have the value "Everything that has a beginning has an end"
.
Arrays
Since version 0.99, Config::Natural
also supports arrays, using the following syntax:
fruits = (
apple
banana
kiwi
orange
)
Arrays can also be appended using the same syntax as for usual values:
fruits = (
apple
banana
)
fruits += (
kiwi
orange
)
The array fruits
now has the same value as in the previous example.
Lists
If you need to write several identical records, you can use lists. The syntax is:
list_name {
parameter = value
text = -
This text may be as long as you wish.
.
}
Example: a version history
## that's the version history of Config::Natural :)
history {
date = 2000.10.10
version = 0.7.0
comment = First fully functional release as an independent module.
}
history {
date = 2000.11.04
version = 0.7.1
comment = Minor change in the internal structure: options are now grouped.
}
history {
date = 2000.11.05
version = 0.8.0
comment = Code cleanup (mainly auto-generation of the options accessors).
comment = Added list support.
}
Lists can be nested. Example:
machine {
name = neutron
sys = linux
service {
type = firewall
importance = critical
}
}
machine {
name = proton
sys = linux
service {
type = proxy
importance = low
}
service {
type = router
importance = medium
}
}
Note that list blocks need not to contain exactly the same set of parameters
If you enable the auto_create_surrounding_list
option, you can then write something like
flavour = lemon
flavour = strawberry
flavour = vanilla
as a shorthand for
flavours {
flavour = lemon
}
flavours {
flavour = strawberry
}
flavours {
flavour = vanilla
}
As you see, Config::Natural
automatically creates a surrounding list around the parameter "flavour"
, and names this list using the plural of the list name, i.e. "flavours"
(ok, I'm only appending a "s" for now ;)
Such a construct can be also be nested.
Note: There must be only one item on each line. This means you can't write:
line { param = value }
but instead
line {
param = value
}
I don't think it's a big deal, because the aim of Config::Natural
is to be fast and to read files with a clear and simple syntax.
Inclusion
You can include a file using the "include"
keyword. For example:
# including some other file
include generic.conf
# now do specific stuff
debug = 0
fast = 1
If the argument is the name of a directory, all the files inside that directory are included. Check read_source() for more information.
Comments
You can use comments in your file. If a line begins with a sharp sign "#"
, it will be ignored. The sharp sign needs not being in the first column though.
SPECIAL FEATURES
Filters
Config::Natural
offer three filter mechanisms so that you can modify the data on-the-fly at two differents moments of the parsing.
file.txt read_source()
___________ _________________
| ... | =====> | reading file |
| foo=hello | | > for each line | _____________
| ... | | X <======|==> | prefilter |
|___________| | v | |_____________|
| parsing line -|--,
|_________________| |
|
param() <----------'
_________________ _____________
| X <=====|==> | data filter |
| v | |_____________|
| X <=====|==> | handler |
| v | |_____________|
| storing value |
|_________________|
Prefilter
Prefilter occurs before Config::Natural
parsing, therefore a prefilter receives the current line as it was read from the file. This can be used in order to correct some names which otherwise couldn't be parsed by Config::Natural
, for example names with spaces. Check in the examples/ directory for sample programs that implements such functions.
You can set up a prefilter using the prefilter()
method, or at creation time with the prefilter
option.
Data filter
Data filter only occurs when affecting values to their parameters. This can be used to implement additional features, like a syntax for interpolating values. Check in the examples/ directory for sample programs that implements such functions.
You can set up a data filter using the filter()
method, or at creation time with the filter
option.
Handlers
Handlers only occurs when affecting values to their parameters, but instead of being object methods, handlers can be seen as "parameters" methods, in that they are bound to a name, and are only called when a parameter with that name is affected.
Handlers are defined with the set_handler()
method.
PARAMETER PATH
This is a new functionality, introduced in version 0.99.
A parameter path is a way of referring any parameter, even if it's deeply buried inside several layers of nested lists. It is used by the method value_of()
to provide a much easier way to read data hidden in nested lists.
The parameter path syntax is loosely inspired by XPath:
path = /level0[index0]/level1[index1]/.../param
Indexes start at zero, like in Perl (and unlike XPath). When an index is omitted, [0]
is assumed.
Examples:
# same as $config->param('myparam')
$value = $config->value_of('/myparam');
# same as $config->param('list')->[0]{myparam}
$value = $config->value_of(/list[0]/myparam);
$value = $config->value_of(/list/myparam);
If you want to get back a whole list, instead of a single value, use [*]
as the last index, and it will return the reference to that list.
# same as $config->param('list')
$value = $config->value_of('/list[*]');
# same as $config->param('list')->[0]{inner_list}
$value = $config->value_of('/list/inner_list[*]');
This syntax also applies to arrays, so when you read
operators = (
Ibuki Maya
Hyuga Makoto
Aoba Shigeru
)
then the following code behaves as expected:
print $nerv->value_of("/operators"); # prints "Ibuki Maya"
print $nerv->value_of("/operators[1]"); # prints "Hyuga Makoto"
$ref = $nerv->value_of("/operators[*]"); # return the corresponding arrayref.
OBJECTS OPTIONS
Syntax Options
If the default symbols used in the configuration file syntax doesn't fit your needs, you can change them using the following methods. Of course you must call these before reading the configuration files.
- affectation_symbol
-
Use this accessor to change the affectation symbol. Default is
"="
. - append_symbol
-
Use this accessor to change the append symbol. Default is
"+"
. - multiline_begin_symbol
-
Use this accessor to change the multiline begin symbol. Default is
"-"
. - multiline_end_symbol
-
Use this accessor to change the multiline end symbol. Default is
"."
. - array_begin_symbol
-
Use this accessor to change the array begin symbol. Default is
"("
. - array_end_symbol
-
Use this accessor to change the array end symbol. Default is
")"
. - comment_line_symbol
-
Use this accessor to change the comment symbol. Default is
"#"
. - list_begin_symbol
-
Use this accessor to change the list begin symbol. Default is
"{"
. - list_end_symbol
-
Use this accessor to change the list end symbol. Default is
"}"
. - include_symbol
-
Use this accessor to change the include symbol. Default is
"include"
.
Other Options
- auto_create_surrounding_list
-
Use this accessor to enable or disable the auto creation of surrounding lists. Default is 0 (disabled).
- case_sensitive
-
Use this accessor to change the case behaviour. Default is 1 (case sensitive).
-
Use this accessor to allow of forbid
Config::Natural
to read hidden files when reading a directory. Default is 0 (don't read hidden files). - strip_indentation
-
Use this accessor to enable
Config::Natural
to automatically strip the indentation from multilines values. For example, when this option is enabled, the following:text = - I thought what I'd do was. I'd pretend I was one of those deaf-mutes or should I? --Laughing Man .
will be converted in
text = - I thought what I'd do was. I'd pretend I was one of those deaf-mutes or should I? --Laughing Man .
This option is disabled by default.
METHODS
- new ( )
- new ( [ OPTIONS, ] FILE )
-
This method creates a new object.
You can give an optional hashref in order to change settings of the object at creation time. Any valid object option can be used here.
my $config = new Config::Natural { read_hidden_files => 1 };
You can also give a file name or a file handle, which will call read_source() with that argument.
# calling with a file name my $config = new Config::Natural 'myconfig.conf'; # calling with a file handle my $config = new Config::Natural \*DATA;
- read_source ( FILENAME )
- read_source ( FILEHANDLE )
-
This method reads the content of the given file and returns an object that contains the data present in that file. The argument can be either a file name or a file handle. This is useful if you want to store your parameters in your program:
use Config::Natural; my $conf = new Config::Natural \*DATA; $conf->param(-debug => 1); ## set debug on if($conf->param('debug')) { print "current options:\n"; print $conf->dump_param(-prefix => ' '); } # ... __END__ ## default values verbose = 1 debug = 0 die_on_errors = 0
If the argument is a directory name, read_source() then recursively reads all the files present in that directory. Invisible files (dot-files) are read only when the option
read_hidden_files
is enabled.You can call the read_source() method several times if you want to merge the settings from different configuration files.
- param ( )
- param ( LIST )
- param ( HASHREF )
-
This is the general purpose manipulating method. It can used to get or set the value of the parameters of an object.
1) Return the list of the parameters:
@params = $conf->param;
2) Return the value of a parameter:
print $conf->param('debug');
3) Return the values of a number of parameters:
@dbg = $conf->param(qw(debug verbose));
4) Set the value of a parameter:
## using CGI.pm-like syntax $conf->param(-debug => 0); ## using a hashref $conf->param({ debug => 0 });
5) Set the values of a number of parameters
## using Perl/Tk-like syntax $conf->param( -warn_non_existant => 1, -mangle => 0 ); ## using a hashref $conf->param( { warn_non_existant => 1, mangle => 0 } );
- param_tree ( )
-
This method returns a hashref that allows direct access to the tree of parameters.
- value_of ( PARAMETER_PATH )
-
This method is an easier way to access the values of the parameters. It returns the value of the parameter path given in argument. Check "PARAMETER PATH" for more information and some examples.
- all_parameters ( )
-
This method returns the list of the parameters of an object.
- delete ( LIST )
-
This method deletes the given parameters.
- delete_all ( )
-
This method deletes all the parameters.
- clear ( LIST )
-
This method sets the given parameters to undef.
- clear_params ( )
-
This method sets all the parameters to undef.
- dump_param ( OPTIONS )
-
This method returns a dump of the parameters as a string using the current format of the
Config::Natural
object. It can be used to simply print them out, or to save them to a configuration file which can be re-read by anotherConfig::Natural
object.Options are passed as a hashref.
Options
nospace
- If you set this option to true, no space will be printed around the affectation symbol.prefix
- If you set this option to a string, it will be printed before printing each parameter.suffix
- If you set this option to a string, it will be printed after printing each parameter.
- write_source ( )
- write_source ( FILENAME [, OPTIONS] )
- write_source ( FILEHANDLE [, OPTIONS] )
-
This method writes the current object to the given file name or file handle. Remaining options, if any, will be passed unmodified to dump_param(). If no argument is given, the file or handle used by the last call of read_source() will be used.
- filter ( CODEREF )
-
This method can be used to set a new data filter. The subroutine code will be considered as an object method and will receive the data as it was read. The return value of the function will be used as the actual value. For example:
sub myfilter { my $self = shift; # important! remember it's a method my $data = shift; $data =~ s/\s*#.*$//go; # remove comments appearing on return $data # an affectation line } my $conf = new Config::Natural { filter => \&myfilter };
- prefilter ( CODEREF )
-
This method can be used to set up a new input prefilter. The same rules as for data filters applies, the only difference being in that the prefilter can modify the data before
Config::Natural
parses it. - set_handler ( PARAM, CODEREF )
-
This method can be used to hook a handler to a particular parameter. The subroutine code will receive the name of the parameter and the value being affected as arguments. The return value of the code will be used as the actual value. An example function could look like this:
sub crypt_handler { my $param = shift; my $value = shift; return crypt($value, $param); } $conf->set_handler('passwd', \&crypt_handler);
- delete_handler ( PARAM )
-
This method can be used to remove the handler of a parameter.
- has_handler ( PARAM )
-
This method checks whether a parameter has a handler or not.
Internal Methods
AUTHOR
Sébastien Aperghis-Tramoni <sebastien@aperghis.net>
BUGS
Please report any bugs or feature requests to bug-config-natural@rt.cpan.org
, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Config-Natural. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
COPYRIGHT & LICENSE
Config::Natural
is Copyright (C)2000-2005 Sébastien Aperghis-Tramoni.
This program is free software. You can redistribute it and/or modify it under the same terms as Perl itself.