The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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 slight dangerous! UNIVERSAL::isa($x, 'My::Class') better not
  # be true in the last case or problems may arrise!
  $obj->baz($x, $y, $z);
  My::Class->baz($x, -z => $z, -y => $y);
  baz($x, -z => $z, -y => $y); # etc...

DESCRIPTION

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 only 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.

ARGUMENTS

The parameters function takes either two or three arguments. If the first argument is a string, it takes three arguments. If the first argument is an array reference, it takes just two.

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.

ARGUMENTS

The final argument to parameters is always the list of arguments passed to the caller.

RESULTS

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 ) ], @_);

SEE ALSO

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

BUGS

This is probably backwards compatible to Perl 5.6 and even earlier but no attempt has been made to test this theory.

I suspect this is rather slower than it could be. I hacked this together in an afternoon without a whole lot of planning.

AUTHOR

Andrew Sterling Hanenkamp, <hanenkamp@users.sourceforge.net>. Contact me at this address for support.

COPYRIGHT AND LICENSE

Copyright 2003 by Andrew Sterling Hanenkamp

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