summaryrefslogtreecommitdiff
path: root/lib/Params/Validate.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Params/Validate.pm')
-rw-r--r--lib/Params/Validate.pm900
1 files changed, 900 insertions, 0 deletions
diff --git a/lib/Params/Validate.pm b/lib/Params/Validate.pm
new file mode 100644
index 0000000..7a5ff01
--- /dev/null
+++ b/lib/Params/Validate.pm
@@ -0,0 +1,900 @@
+package Params::Validate;
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+our $VERSION = '1.20';
+
+use Exporter;
+use Module::Implementation;
+use Params::Validate::Constants;
+
+use vars qw( $NO_VALIDATION %OPTIONS $options );
+
+our @ISA = 'Exporter';
+
+my @types = qw(
+ SCALAR
+ ARRAYREF
+ HASHREF
+ CODEREF
+ GLOB
+ GLOBREF
+ SCALARREF
+ HANDLE
+ BOOLEAN
+ UNDEF
+ OBJECT
+);
+
+our %EXPORT_TAGS = (
+ 'all' => [
+ qw( validate validate_pos validation_options validate_with ),
+ @types
+ ],
+ types => \@types,
+);
+
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} }, 'set_options' );
+our @EXPORT = qw( validate validate_pos );
+
+$NO_VALIDATION = $ENV{PERL_NO_VALIDATION};
+
+{
+ my $loader = Module::Implementation::build_loader_sub(
+ implementations => [ 'XS', 'PP' ],
+ symbols => [
+ qw(
+ validate
+ validate_pos
+ validate_with
+ validation_options
+ set_options
+ ),
+ ],
+ );
+
+ $ENV{PARAMS_VALIDATE_IMPLEMENTATION} = 'PP' if $ENV{PV_TEST_PERL};
+
+ $loader->();
+}
+
+1;
+
+# ABSTRACT: Validate method/function parameters
+
+__END__
+
+=pod
+
+=head1 NAME
+
+Params::Validate - Validate method/function parameters
+
+=head1 VERSION
+
+version 1.20
+
+=head1 SYNOPSIS
+
+ use Params::Validate qw(:all);
+
+ # takes named params (hash or hashref)
+ sub foo {
+ validate(
+ @_, {
+ foo => 1, # mandatory
+ bar => 0, # optional
+ }
+ );
+ }
+
+ # takes positional params
+ sub bar {
+ # first two are mandatory, third is optional
+ validate_pos( @_, 1, 1, 0 );
+ }
+
+ sub foo2 {
+ validate(
+ @_, {
+ foo =>
+ # specify a type
+ { type => ARRAYREF },
+ bar =>
+ # specify an interface
+ { can => [ 'print', 'flush', 'frobnicate' ] },
+ baz => {
+ type => SCALAR, # a scalar ...
+ # ... that is a plain integer ...
+ regex => qr/^\d+$/,
+ callbacks => { # ... and smaller than 90
+ 'less than 90' => sub { shift() < 90 },
+ },
+ }
+ }
+ );
+ }
+
+ sub callback_with_custom_error {
+ validate(
+ @_,
+ {
+ foo => callbacks => {
+ 'is an integer' => sub {
+ return 1 if $_[0] =~ /^-?[1-9][0-9]*$/;
+ die "$_[0] is not a valid integer value";
+ },
+ }
+ }
+ );
+ }
+
+ sub with_defaults {
+ my %p = validate(
+ @_, {
+ # required
+ foo => 1,
+ # $p{bar} will be 99 if bar is not given. bar is now
+ # optional.
+ bar => { default => 99 }
+ }
+ );
+ }
+
+ sub pos_with_defaults {
+ my @p = validate_pos( @_, 1, { default => 99 } );
+ }
+
+ sub sets_options_on_call {
+ my %p = validate_with(
+ params => \@_,
+ spec => { foo => { type => SCALAR, default => 2 } },
+ normalize_keys => sub { $_[0] =~ s/^-//; lc $_[0] },
+ );
+ }
+
+=head1 DESCRIPTION
+
+The Params::Validate module allows you to validate method or function
+call parameters to an arbitrary level of specificity. At the simplest
+level, it is capable of validating the required parameters were given
+and that no unspecified additional parameters were passed in.
+
+It is also capable of determining that a parameter is of a specific
+type, that it is an object of a certain class hierarchy, that it
+possesses certain methods, or applying validation callbacks to
+arguments.
+
+=head2 EXPORT
+
+The module always exports the C<validate()> and C<validate_pos()>
+functions.
+
+It also has an additional function available for export,
+C<validate_with>, which can be used to validate any type of
+parameters, and set various options on a per-invocation basis.
+
+In addition, it can export the following constants, which are used as
+part of the type checking. These are C<SCALAR>, C<ARRAYREF>,
+C<HASHREF>, C<CODEREF>, C<GLOB>, C<GLOBREF>, and C<SCALARREF>,
+C<UNDEF>, C<OBJECT>, C<BOOLEAN>, and C<HANDLE>. These are explained
+in the section on L<Type Validation|Params::Validate/Type Validation>.
+
+The constants are available via the export tag C<:types>. There is
+also an C<:all> tag which includes all of the constants as well as the
+C<validation_options()> function.
+
+=encoding UTF-8
+
+=head1 PARAMETER VALIDATION
+
+The validation mechanisms provided by this module can handle both
+named or positional parameters. For the most part, the same features
+are available for each. The biggest difference is the way that the
+validation specification is given to the relevant subroutine. The
+other difference is in the error messages produced when validation
+checks fail.
+
+When handling named parameters, the module will accept either a hash
+or a hash reference.
+
+Subroutines expecting named parameters should call the C<validate()>
+subroutine like this:
+
+ validate(
+ @_, {
+ parameter1 => validation spec,
+ parameter2 => validation spec,
+ ...
+ }
+ );
+
+Subroutines expecting positional parameters should call the
+C<validate_pos()> subroutine like this:
+
+ validate_pos( @_, { validation spec }, { validation spec } );
+
+=head2 Mandatory/Optional Parameters
+
+If you just want to specify that some parameters are mandatory and
+others are optional, this can be done very simply.
+
+For a subroutine expecting named parameters, you would do this:
+
+ validate( @_, { foo => 1, bar => 1, baz => 0 } );
+
+This says that the "foo" and "bar" parameters are mandatory and that
+the "baz" parameter is optional. The presence of any other
+parameters will cause an error.
+
+For a subroutine expecting positional parameters, you would do this:
+
+ validate_pos( @_, 1, 1, 0, 0 );
+
+This says that you expect at least 2 and no more than 4 parameters.
+If you have a subroutine that has a minimum number of parameters but
+can take any maximum number, you can do this:
+
+ validate_pos( @_, 1, 1, (0) x (@_ - 2) );
+
+This will always be valid as long as at least two parameters are
+given. A similar construct could be used for the more complex
+validation parameters described further on.
+
+Please note that this:
+
+ validate_pos( @_, 1, 1, 0, 1, 1 );
+
+makes absolutely no sense, so don't do it. Any zeros must come at the
+end of the validation specification.
+
+In addition, if you specify that a parameter can have a default, then
+it is considered optional.
+
+=head2 Type Validation
+
+This module supports the following simple types, which can be
+L<exported as constants|/EXPORT>:
+
+=over 4
+
+=item * SCALAR
+
+A scalar which is not a reference, such as C<10> or C<'hello'>. A
+parameter that is undefined is B<not> treated as a scalar. If you
+want to allow undefined values, you will have to specify C<SCALAR |
+UNDEF>.
+
+=item * ARRAYREF
+
+An array reference such as C<[1, 2, 3]> or C<\@foo>.
+
+=item * HASHREF
+
+A hash reference such as C<< { a => 1, b => 2 } >> or C<\%bar>.
+
+=item * CODEREF
+
+A subroutine reference such as C<\&foo_sub> or C<sub { print "hello" }>.
+
+=item * GLOB
+
+This one is a bit tricky. A glob would be something like C<*FOO>, but
+not C<\*FOO>, which is a glob reference. It should be noted that this
+trick:
+
+ my $fh = do { local *FH; };
+
+makes C<$fh> a glob, not a glob reference. On the other hand, the
+return value from C<Symbol::gensym> is a glob reference. Either can
+be used as a file or directory handle.
+
+=item * GLOBREF
+
+A glob reference such as C<\*FOO>. See the L<GLOB|GLOB> entry above
+for more details.
+
+=item * SCALARREF
+
+A reference to a scalar such as C<\$x>.
+
+=item * UNDEF
+
+An undefined value
+
+=item * OBJECT
+
+A blessed reference.
+
+=item * BOOLEAN
+
+This is a special option, and is just a shortcut for C<UNDEF | SCALAR>.
+
+=item * HANDLE
+
+This option is also special, and is just a shortcut for C<GLOB |
+GLOBREF>. However, it seems likely that most people interested in
+either globs or glob references are likely to really be interested in
+whether the parameter in question could be a valid file or directory
+handle.
+
+=back
+
+To specify that a parameter must be of a given type when using named
+parameters, do this:
+
+ validate(
+ @_, {
+ foo => { type => SCALAR },
+ bar => { type => HASHREF }
+ }
+ );
+
+If a parameter can be of more than one type, just use the bitwise or
+(C<|>) operator to combine them.
+
+ validate( @_, { foo => { type => GLOB | GLOBREF } );
+
+For positional parameters, this can be specified as follows:
+
+ validate_pos( @_, { type => SCALAR | ARRAYREF }, { type => CODEREF } );
+
+=head2 Interface Validation
+
+To specify that a parameter is expected to have a certain set of
+methods, we can do the following:
+
+ validate(
+ @_, {
+ foo =>
+ # just has to be able to ->bar
+ { can => 'bar' }
+ }
+ );
+
+ ... or ...
+
+ validate(
+ @_, {
+ foo =>
+ # must be able to ->bar and ->print
+ { can => [qw( bar print )] }
+ }
+ );
+
+=head2 Class Validation
+
+A word of warning. When constructing your external interfaces, it is
+probably better to specify what methods you expect an object to
+have rather than what class it should be of (or a child of). This
+will make your API much more flexible.
+
+With that said, if you want to validate that an incoming parameter
+belongs to a class (or child class) or classes, do:
+
+ validate(
+ @_,
+ { foo => { isa => 'My::Frobnicator' } }
+ );
+
+ ... or ...
+
+ validate(
+ @_,
+ # must be both, not either!
+ { foo => { isa => [qw( My::Frobnicator IO::Handle )] } }
+ );
+
+=head2 Regex Validation
+
+If you want to specify that a given parameter must match a specific
+regular expression, this can be done with "regex" spec key. For
+example:
+
+ validate(
+ @_,
+ { foo => { regex => qr/^\d+$/ } }
+ );
+
+The value of the "regex" key may be either a string or a pre-compiled
+regex created via C<qr>.
+
+If the value being checked against a regex is undefined, the regex is
+explicitly checked against the empty string ('') instead, in order to
+avoid "Use of uninitialized value" warnings.
+
+The C<Regexp::Common> module on CPAN is an excellent source of regular
+expressions suitable for validating input.
+
+=head2 Callback Validation
+
+If none of the above are enough, it is possible to pass in one or more
+callbacks to validate the parameter. The callback will be given the
+B<value> of the parameter as its first argument. Its second argument
+will be all the parameters, as a reference to either a hash or array.
+Callbacks are specified as hash reference. The key is an id for the
+callback (used in error messages) and the value is a subroutine
+reference, such as:
+
+ validate(
+ @_,
+ {
+ foo => {
+ callbacks => {
+ 'smaller than a breadbox' => sub { shift() < $breadbox },
+ 'green or blue' => sub {
+ return 1 if $_[0] eq 'green' || $_[0] eq 'blue';
+ die "$_[0] is not green or blue!";
+ }
+ }
+ }
+ }
+ );
+
+ validate(
+ @_, {
+ foo => {
+ callbacks => {
+ 'bigger than baz' => sub { $_[0] > $_[1]->{baz} }
+ }
+ }
+ }
+ );
+
+The callback should return a true value if the value is valid. If not, it can
+return false or die. If you return false, a generic error message will be
+thrown by C<Params::Validate>.
+
+If your callback dies instead you can provide a custom error message. If the
+callback dies with a plain string, this string will be appended to an
+exception message generated by C<Params::Validate>. If the callback dies with
+a reference (blessed or not), then this will be rethrown as-is by
+C<Params::Validate>.
+
+=head2 Untainting
+
+If you want values untainted, set the "untaint" key in a spec hashref
+to a true value, like this:
+
+ my %p = validate(
+ @_, {
+ foo => { type => SCALAR, untaint => 1 },
+ bar => { type => ARRAYREF }
+ }
+ );
+
+This will untaint the "foo" parameter if the parameters are valid.
+
+Note that untainting is only done if I<all parameters> are valid.
+Also, only the return values are untainted, not the original values
+passed into the validation function.
+
+Asking for untainting of a reference value will not do anything, as
+C<Params::Validate> will only attempt to untaint the reference itself.
+
+=head2 Mandatory/Optional Revisited
+
+If you want to specify something such as type or interface, plus the
+fact that a parameter can be optional, do this:
+
+ validate(
+ @_, {
+ foo => { type => SCALAR },
+ bar => { type => ARRAYREF, optional => 1 }
+ }
+ );
+
+or this for positional parameters:
+
+ validate_pos(
+ @_,
+ { type => SCALAR },
+ { type => ARRAYREF, optional => 1 }
+ );
+
+By default, parameters are assumed to be mandatory unless specified as
+optional.
+
+=head2 Dependencies
+
+It also possible to specify that a given optional parameter depends on
+the presence of one or more other optional parameters.
+
+ validate(
+ @_, {
+ cc_number => {
+ type => SCALAR,
+ optional => 1,
+ depends => [ 'cc_expiration', 'cc_holder_name' ],
+ },
+ cc_expiration => { type => SCALAR, optional => 1 },
+ cc_holder_name => { type => SCALAR, optional => 1 },
+ }
+ );
+
+In this case, "cc_number", "cc_expiration", and "cc_holder_name" are
+all optional. However, if "cc_number" is provided, then
+"cc_expiration" and "cc_holder_name" must be provided as well.
+
+This allows you to group together sets of parameters that all must be
+provided together.
+
+The C<validate_pos()> version of dependencies is slightly different,
+in that you can only depend on one other parameter. Also, if for
+example, the second parameter 2 depends on the fourth parameter, then
+it implies a dependency on the third parameter as well. This is
+because if the fourth parameter is required, then the user must also
+provide a third parameter so that there can be four parameters in
+total.
+
+C<Params::Validate> will die if you try to depend on a parameter not
+declared as part of your parameter specification.
+
+=head2 Specifying defaults
+
+If the C<validate()> or C<validate_pos()> functions are called in a list
+context, they will return a hash or containing the original parameters plus
+defaults as indicated by the validation spec.
+
+If the function is not called in a list context, providing a default
+in the validation spec still indicates that the parameter is optional.
+
+The hash or array returned from the function will always be a copy of
+the original parameters, in order to leave C<@_> untouched for the
+calling function.
+
+Simple examples of defaults would be:
+
+ my %p = validate( @_, { foo => 1, bar => { default => 99 } } );
+
+ my @p = validate_pos( @_, 1, { default => 99 } );
+
+In scalar context, a hash reference or array reference will be
+returned, as appropriate.
+
+=head1 USAGE NOTES
+
+=head2 Validation failure
+
+By default, when validation fails C<Params::Validate> calls
+C<Carp::confess()>. This can be overridden by setting the C<on_fail>
+option, which is described in the L<"GLOBAL" OPTIONS|"GLOBAL" OPTIONS>
+section.
+
+=head2 Method calls
+
+When using this module to validate the parameters passed to a method
+call, you will probably want to remove the class/object from the
+parameter list B<before> calling C<validate()> or C<validate_pos()>.
+If your method expects named parameters, then this is necessary for
+the C<validate()> function to actually work, otherwise C<@_> will not
+be usable as a hash, because it will first have your object (or
+class) B<followed> by a set of keys and values.
+
+Thus the idiomatic usage of C<validate()> in a method call will look
+something like this:
+
+ sub method {
+ my $self = shift;
+
+ my %params = validate(
+ @_, {
+ foo => 1,
+ bar => { type => ARRAYREF },
+ }
+ );
+ }
+
+=head2 Speeding Up Validation
+
+In most cases, the validation spec will remain the same for each call to a
+subroutine. In that case, you can speed up validation by defining the
+validation spec just once, rather than on each call to the subroutine:
+
+ my %spec = ( ... );
+ sub foo {
+ my %params = validate( @_, \%spec );
+ }
+
+You can also use the C<state> feature to do this:
+
+ use feature 'state';
+
+ sub foo {
+ state $spec = { ... };
+ my %params = validate( @_, $spec );
+ }
+
+=head1 "GLOBAL" OPTIONS
+
+Because the API for the C<validate()> and C<validate_pos()> functions does not
+make it possible to specify any options other than the validation spec, it is
+possible to set some options as pseudo-'globals'. These allow you to specify
+such things as whether or not the validation of named parameters should be
+case sensitive, for one example.
+
+These options are called pseudo-'globals' because these settings are
+B<only applied to calls originating from the package that set the
+options>.
+
+In other words, if I am in package C<Foo> and I call
+C<validation_options()>, those options are only in effect when I call
+C<validate()> from package C<Foo>.
+
+While this is quite different from how most other modules operate, I
+feel that this is necessary in able to make it possible for one
+module/application to use Params::Validate while still using other
+modules that also use Params::Validate, perhaps with different
+options set.
+
+The downside to this is that if you are writing an app with a standard
+calling style for all functions, and your app has ten modules, B<each
+module must include a call to C<validation_options()>>. You could of
+course write a module that all your modules use which uses various
+trickery to do this when imported.
+
+=head2 Options
+
+=over 4
+
+=item * normalize_keys => $callback
+
+This option is only relevant when dealing with named parameters.
+
+This callback will be used to transform the hash keys of both the
+parameters and the parameter spec when C<validate()> or
+C<validate_with()> are called.
+
+Any alterations made by this callback will be reflected in the
+parameter hash that is returned by the validation function. For
+example:
+
+ sub foo {
+ return validate_with(
+ params => \@_,
+ spec => { foo => { type => SCALAR } },
+ normalize_keys =>
+ sub { my $k = shift; $k =~ s/^-//; return uc $k },
+ );
+
+ }
+
+ %p = foo( foo => 20 );
+
+ # $p{FOO} is now 20
+
+ %p = foo( -fOo => 50 );
+
+ # $p{FOO} is now 50
+
+The callback must return a defined value.
+
+If a callback is given then the deprecated "ignore_case" and
+"strip_leading" options are ignored.
+
+=item * allow_extra => $boolean
+
+If true, then the validation routine will allow extra parameters not
+named in the validation specification. In the case of positional
+parameters, this allows an unlimited number of maximum parameters
+(though a minimum may still be set). Defaults to false.
+
+=item * on_fail => $callback
+
+If given, this callback will be called whenever a validation check
+fails. It will be called with a single parameter, which will be a
+string describing the failure. This is useful if you wish to have
+this module throw exceptions as objects rather than as strings, for
+example.
+
+This callback is expected to C<die()> internally. If it does not, the
+validation will proceed onwards, with unpredictable results.
+
+The default is to simply use the Carp module's C<confess()> function.
+
+=item * stack_skip => $number
+
+This tells Params::Validate how many stack frames to skip when finding
+a subroutine name to use in error messages. By default, it looks one
+frame back, at the immediate caller to C<validate()> or
+C<validate_pos()>. If this option is set, then the given number of
+frames are skipped instead.
+
+=item * ignore_case => $boolean
+
+DEPRECATED
+
+This is only relevant when dealing with named parameters. If it is
+true, then the validation code will ignore the case of parameter
+names. Defaults to false.
+
+=item * strip_leading => $characters
+
+DEPRECATED
+
+This too is only relevant when dealing with named parameters. If this
+is given then any parameters starting with these characters will be
+considered equivalent to parameters without them entirely. For
+example, if this is specified as '-', then C<-foo> and C<foo> would be
+considered identical.
+
+=back
+
+=head1 PER-INVOCATION OPTIONS
+
+The C<validate_with()> function can be used to set the options listed
+above on a per-invocation basis. For example:
+
+ my %p = validate_with(
+ params => \@_,
+ spec => {
+ foo => { type => SCALAR },
+ bar => { default => 10 }
+ },
+ allow_extra => 1,
+ );
+
+In addition to the options listed above, it is also possible to set
+the option "called", which should be a string. This string will be
+used in any error messages caused by a failure to meet the validation
+spec.
+
+This subroutine will validate named parameters as a hash if the "spec"
+parameter is a hash reference. If it is an array reference, the
+parameters are assumed to be positional.
+
+ my %p = validate_with(
+ params => \@_,
+ spec => {
+ foo => { type => SCALAR },
+ bar => { default => 10 }
+ },
+ allow_extra => 1,
+ called => 'The Quux::Baz class constructor',
+ );
+
+ my @p = validate_with(
+ params => \@_,
+ spec => [
+ { type => SCALAR },
+ { default => 10 }
+ ],
+ allow_extra => 1,
+ called => 'The Quux::Baz class constructor',
+ );
+
+=head1 DISABLING VALIDATION
+
+If the environment variable C<PERL_NO_VALIDATION> is set to something
+true, then validation is turned off. This may be useful if you only
+want to use this module during development but don't want the speed
+hit during production.
+
+The only error that will be caught will be when an odd number of
+parameters are passed into a function/method that expects a hash.
+
+If you want to selectively turn validation on and off at runtime, you
+can directly set the C<$Params::Validate::NO_VALIDATION> global
+variable. It is B<strongly> recommended that you B<localize> any
+changes to this variable, because other modules you are using may
+expect validation to be on when they execute. For example:
+
+ {
+ local $Params::Validate::NO_VALIDATION = 1;
+
+ # no error
+ foo( bar => 2 );
+ }
+
+ # error
+ foo( bar => 2 );
+
+ sub foo {
+ my %p = validate( @_, { foo => 1 } );
+ ...;
+ }
+
+But if you want to shoot yourself in the foot and just turn it off, go
+ahead!
+
+=head1 TAINT MODE
+
+The XS implementation of this module has some problems Under taint mode with
+version of Perl before 5.14. If validation I<fails>, then instead of getting
+the expected error message you'll get a message like "Insecure dependency in
+eval_sv". This can be worked around by either untainting the arguments
+yourself, using the pure Perl implementation, or upgrading your Perl.
+
+=head1 LIMITATIONS
+
+Right now there is no way (short of a callback) to specify that
+something must be of one of a list of classes, or that it must possess
+one of a list of methods. If this is desired, it can be added in the
+future.
+
+Ideally, there would be only one validation function. If someone
+figures out how to do this, please let me know.
+
+=head1 SUPPORT
+
+Please submit bugs and patches to the CPAN RT system at
+http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Params%3A%3AValidate or
+via email at bug-params-validate@rt.cpan.org.
+
+Support questions can be sent to Dave at autarch@urth.org.
+
+=head1 DONATIONS
+
+If you'd like to thank me for the work I've done on this module,
+please consider making a "donation" to me via PayPal. I spend a lot of
+free time creating free software, and would appreciate any support
+you'd care to offer.
+
+Please note that B<I am not suggesting that you must do this> in order
+for me to continue working on this particular software. I will
+continue to do so, inasmuch as I have in the past, for as long as it
+interests me.
+
+Similarly, a donation made in this way will probably not make me work
+on this software much more, unless I get so many donations that I can
+consider working on free software full time, which seems unlikely at
+best.
+
+To donate, log into PayPal and send money to autarch@urth.org or use
+the button on this page:
+L<http://www.urth.org/~autarch/fs-donation.html>
+
+=head1 AUTHORS
+
+=over 4
+
+=item *
+
+Dave Rolsky <autarch@urth.org>
+
+=item *
+
+Ilya Martynov <ilya@martynov.org>
+
+=back
+
+=head1 CONTRIBUTORS
+
+=for stopwords Ivan Bessarabov J.R. Mash Noel Maddy Olivier Mengué Vincent Pit
+
+=over 4
+
+=item *
+
+Ivan Bessarabov <ivan@bessarabov.ru>
+
+=item *
+
+J.R. Mash <jmash.code@gmail.com>
+
+=item *
+
+Noel Maddy <zhtwnpanta@gmail.com>
+
+=item *
+
+Olivier Mengué <dolmen@cpan.org>
+
+=item *
+
+Vincent Pit <perl@profvince.com>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is Copyright (c) 2001 - 2015 by Dave Rolsky and Ilya Martynov.
+
+This is free software, licensed under:
+
+ The Artistic License 2.0 (GPL Compatible)
+
+=cut