Config-Scoped
view release on metacpan or search on metacpan
* macro name
* macro value
* include path
* warning name
Any token may be quoted.
Tokens that contain special characters must be quoted. The special
characters are
\s {} [] <> () ; , ' " = # %
Config::Scoped uses the Perl quoting syntax.
Tokens may be quoted with either single or double quotes
a = 'New York'
b = "New Jersey\n"
Here-docs are supported
a = <<EOT
New York
New Jersey
EOT
but generalized quotes (q(), qq(), etc.) are not. Text in here-docs is
regarded as single-quoted if the delimiter is enclosed in single quotes,
and double-quoted if the delimiter is enclosed in double quotes or
unquoted.
Double-quoted tokens are evaluated as Perl strings inside the parser's
Safe compartment. They are subject to the usual Perl backslash and
variable interpolation, as well as macro expansion. Variables to be
interpolated are passed via the Safe compartment, as shown above in
"Perl code evaluation". If you need a literal $ or @ in a double-quoted
string, be sure to escape it with a backslash (\) to suppress
interpolation.
An
eval { ... }
may appear anywhere that a token is expected. For example
foo {
eval { 'b' . 'c' } = 1
}
parses to
$cfg_hash = { foo => { bc => 1 } }
DIRECTIVES
Config::Scoped has three directives: %macro, %warning, and %include.
Macros
Config::Scoped supports macros. A macro is defined with
%macro name value
Macros may be defined
* at file scope
* within anonymous blocks
* within declaration blocks
* within hash blocks
Macros defined within blocks are lexically scoped to those blocks.
Macro substitution occurs
* within any double-quoted text
* within the entirety of Perl eval blocks
* nowhere else
Include files
Config::Scoped supports include files.
To include one config file within another, write
%include path/to/file
%include directives may appear
* at file scope
* within anonymous blocks
* nowhere else
In particular, %include directives may not appear within declaration
blocks or hash blocks.
Parameters and macros in include files are imported to the current
scope. You can control this scope with an anonymous block
{
%include dog.cfg
dog { } # sees imports from dog.cfg
}
bird { } # does not see imports from dog.cfg
Warnings are scoped to the included file and do not leak to the parent
file.
Pathnames are either
* absolute
* relative to the dirname of the current configuration file
For example, this config
# in configuration file /etc/myapp/global.cfg
%include shared.cfg
includes the file /etc/myapp/shared.cfg.
When parsing a configuration string, the path is relative to the current
working directory.
Include files are not actually included as text. Rather, they are
processed by a recursive call to Config::Scoped. Subclass implementers
may need to be aware of this.
Warnings
Config::Scoped can check for 5 problems with config files
Perl data
Config::Scoped accepts most Perl data syntax. This allows Perl data to
pulled into config files largely unaltered
foo
{
a = 1;
b = [ 'red', 'green', 'blue' ];
c = { x => 5,
y => 6 };
}
However, Config::Scoped doesn't require as much punctuation as Perl, and
config files written from scratch will be cleaner without it
foo
{
a = 1
b = [ red green blue ]
c = { x => 5
y => 6 }
}
Anonymous blocks
Don't use anonymous blocks unless you need to restrict the scope of
something. In particular, there is no need for a top-level anonymous
block around the whole config file
{ # unnecessary
foo { }
}
Inheritance
Parameters that are outside of a declaration are inherited by all
following declarations in their scope. Don't do this unless you mean it
wheels = 4
car
{
# OK
}
cat
{
# I can haz weelz?
}
Blocks, blocks, we got blocks...
Config::Scoped has four different kinds of blocks
* anonymous
* declaration
* eval
* hash
They all look the same, but they aren't, and they have different rules
and restrictions. See "CONFIG FILE FORMAT" for descriptions of each.
Macros
Macros are evil, and Config::Scoped macros are specially evil, because
* they don't respect token boundaries
* where multiple substitutions are possible, the substitution order is
undefined
* substituted text may or may not be rescanned for further
substitutions
Caveat scriptor.
SUBCLASSING
Config::Scoped has no formally defined subclass interface. Here are some
guidelines for writing subclasses. Implementers who override (or
redefine) base class methods may need to read the Config::Scoped sources
for more information.
Arbitrary
$your_key => $value
pairs may be passed to the Config::Scoped constructor. They will be
stored in the $cs->{local} hashref, and methods may access them with
code like
$cs->{local}{$your_key}
To avoid conflict with existing keys in the local hash, consider
distinguishing your keys with a unique prefix.
Arbitrary warning names may be defined, set with new and set_warnings,
used in %warnings directives, and tested with warnings_on. Methods can
call warnings_on to find out whether a warning is currently enabled.
All methods throw exceptions (die) on error. The exception object should
be a subclass of Config::Scoped::Error. You can use one of the classes
defined in Config::Scoped::Error, or you can derive your own. This code
Config::Scoped::Error->throw(
-file => $cs->_get_file(%args),
-line => $cs->_get_line(%args),
-text => $message,
);
will generate an error message that reports the location in the config
file where the error was detected, rather than a location in Perl code.
Config::Scoped performs validation checks on the elements of
configuration files (declarations, parameters, macros, etc). Here are
the interfaces to the validation methods. Subclasses can override these
methods to modify or extend the validation checks.
$macro_value = $cs->macro_validate>(name => $name, value => $value)
Called for each %macro directive.
Receives the $name and $value from the directive. The returned
$macro_value becomes the actual value of the macro.
If the macro is invalid, throws a
Config::Scoped::Error::Validate::Macro exception.
$param_value = $cs->parameter_validate>(name => $name, value => $value)
Called for each parameter definition.
Receives the $name and $value from the definition. The returned
$param_value becomes the actual value of the parameter.
If the parameter is invalid, throws a
Config::Scoped::Error::Validate::Parameter exception.
$cs->declaration_validate(name => $name, value => $value, tail => $tail)
Called for each declaration.
$name is an array ref giving the chain of names for the declaration
block. $value is a hash ref containing all the parameters in the
declaration block. $tail is a hash ref containing all the parameters
in any previously defined declaration with the same name(s).
For example, the declaration
foo bar baz { a=1 b=2 }
leads to the call
$cs->declaration_validate(name => [ qw(foo bar baz) ],
value => { a => '1', b => '2' },
tail => $cs->{local}{config}{foo}{bar}{baz});
The method can test %$tail to discover if there is an existing,
non-empty declaration with the same name(s).
The method has no return value. However, the method can alter the
contents of %$value. Upon return, the parameters in %$value become
the actual contents of the declaration block.
If the declaration is invalid, throws a
Config::Scoped::Error::Validate::Declaration exception.
$cs->permissions_validate(file => $file, handle => $handle)
Called for the config file, each included file, and each retrieved
cache file. One of $file or $handle must be non-null.
Throws a Config::Scoped::Error::Validate::Permissions exception if
the file is not safe to read.
SEE ALSO
* Error
* Safe
* Config::Scoped::Error
* Parse::RecDescent
* "Quote and Quote-like Operators" in perlop
TODO
Tests
Still more tests needed.
( run in 0.783 second using v1.01-cache-2.11-cpan-5837b0d9d2c )