NAME

Getargs::Mixed - Perl extension allowing subs to handle mixed parameter lists

SYNOPSIS

use Getargs::Mixed;

sub foo {
    my %args = parameters([ qw( x y z ) ], @_);

    # Do stuff with @args{qw(x y z)}
}

# OR if you have object-oriented syntax
sub bar {
    my ($self, %args) = parameters('self', [ qw( x y z ) ], @_);

    # Do stuff with @args{qw(x y z)}
}

# OR if you have mixed OO and function syntax
sub baz {
    my ($self, %args) = parameters('My::Class', [ qw( x y z ) ], @_);

    # Do stuff with @args{qw(x y z)}
}

# Calling foo:
foo($x, $y, $z);
foo($x, -z => $z, -y => $y);
foo(-z => $z, -x => $x, -y => $y);

# ERRORS! calling foo:
foo(-z => $z, $x, $y);          ### <-- ERROR!
foo(x => $x, y => $y, z => $z); ### <-- ERROR!
foo($x, -y => $y, $z);          ### <-- ERROR!
foo($x, $y, $z, -x => $blah);   ### <-- ERROR!

# Calling bar:
$obj->bar($x, $y, $z);
$obj->bar($x, -z => $z, -y => $y);
My::Class->bar(-z => $z, -x => $x, -y => $y); # etc...

# Calling baz is slightly dangerous! UNIVERSAL::isa($x, 'My::Class') better
# not be true in the last case or problems may arise!
$obj->baz($x, $y, $z);
My::Class->baz($x, -z => $z, -y => $y);
baz($x, -z => $z, -y => $y); # etc...

FUNCTIONAL INTERFACE

parameters

This allows for the handling mixed argument lists to subroutines. It is meant to be flexible and lightweight. It doesn't do any "type-checking", it simply turns your parameter lists into hash according to a simple specification.

The main function in this module is parameters and it handles all the work of figuring out which parameters have been sent and which have not. When it detects an error, it will die with Carp::confess.

The parameters function takes either two or three arguments. If the first argument is a string, it takes at least two arguments: invocant and specification. For example:

parameters('invocant', [qw(specification)], @_);

If the first argument is an array reference, it takes at least one argument: the specification. For example:

parameters([qw(specification)], @_);

In either case, the specification is followed by any arguments to be parsed (@_ in the examples above).

Invocant

If the first parameter is a string, it should either be a package name or the special string "self". Passing "self" in this argument will cause the parameters function to require an invocant on the method--that is, it must be called like this:

$obj->foo($a, $b, $c); # OR
foo $obj ($a, $b, $c); # often seen as new My::Class (...)

where $obj is either a blessed reference, package name, or a scalar containing a package name.

If, instead, the first parameter is a string, but not equal to "self". The string is considered to be a package name. In this case, parameters tries to guess how the method is being called. This has a lot of potential caveats, so beware! Essentially, parameters will check to see if the first argument is a subclass of the given package name (i.e., according to UNIVERSAL::isa. If so, it will ASSUME (pronounced Ass-You-Me) that the argument is the invocant. Otherwise, it will ASSUME that the argument is the first parameter. In this case, the returned list will contain the given package name as the first element before the list of pairs even though no invocant was actually used.

Specification

The array reference argument to parameters contains a list of variable names that the caller accepts. The parameter list is ordered so that if the user passes positional parameters, the same order the parameters are placed, will be the order used to set the variables in the returned hash. The list may contain a single semicolon, which tells parameters that all parameters up to that point are required and all following are optional. If no semicolon exists, then parameters will consider all to be required and die when one of the required parameters is missing.

Finally, the list may end with a '*' which will cause parameters to collect any extra unexpected named or positional parameters. Extra named parameters will be inserted into the returned arguments list. Extra positional parameters will be placed in array reference and assigned to the '*' key of the returned arguments list. If '*' is not specified and extra arguments are found parameters will die.

The arguments to be parsed

The final argument to parameters is always the list of arguments passed to the caller, usually @_.

The results of a parameters() call

The result returned from the parameters function depends on whether there are two arguments or three. If parameters is called with two arguments, then a list of pairs (a hash) is returned. If parameters is called with three arguments, then an invocant is prepended to the list of pairs first. If the first argument is not "self", then the invocant will be set to the first argument if parameters doesn't detect any invocant.

ARGUMENT PARSING

The way parameters handles arguments is relatively flexible. However, the format must always specify all positional parameters first, if any, followed by all positional parameters. The parameters function switches from positional to named parameters when it encounters the first string preceded with a hypen ('-'). This may have the unfortunate side effect of causing normal parameters to be misinterpreted as named parameters. If this may be the case with your usage, I suggest finding another solution--or modifying this module to suit. A safe solution to this is to always use named parameters--at which point you might as well not use this module anyway.

EXPORT

Always exports parameters by default. If you do not want this, use:

use Getargs::Mixed ();
# OR
require Getargs::Mixed;

# ...
my %args = Getargs::Mixed::parameters([ qw( x y z ) ], @_);

OBJECT-ORIENTED INTERFACE

Getargs::Mixed supports an object-oriented interface that permits you to adjust how the parameters are processed. For example:

my $getargs = Getargs::Mixed->new([options...]);
my %args = $getargs->parameters([ qw( x y z ) ], @_);

The arguments to the parameters method are exactly the same as when parameters is called as a function. This includes the invocant, since $getargs is not the invocant of the function that is invoking $getargs->parameters().

new

Create a new instance with the given options. For example:

my $getargs = Getargs::Mixed->new(-undef_ok => 1);

Currently known options are:

-undef_ok

The option -undef_ok => 1 permits the value of a parameter to be undef. For example,

my %args = parameters(['foo'], -foo => undef);

will fail with a message that required argument foo was not provided, but

my %args = Getargs::Mixed->new(-undef_ok => 1)
                         ->parameters(['foo'], -foo => undef);

will succeed, and set $args{foo} to undef.

SEE ALSO

Other similar modules to this one that I'm aware of include: Getargs::Long, Getopt::GetArgs, and Smart::Args.

AUTHOR

Andrew Sterling Hanenkamp, <hanenkamp@users.sourceforge.net> (HANENKAMP). Additional code by Christopher White (CXW).

COPYRIGHT AND LICENSE

Copyright 2003--2019 by Andrew Sterling Hanenkamp and Christopher White. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.