NAME

Params::Get - Normalise subroutine arguments regardless of calling convention

VERSION

Version 0.15

DESCRIPTION

Params::Get exports a single function, get_params, which accepts a caller's argument list (or a reference to it) in any of the common Perl calling conventions and returns a unified hash-ref. Library authors can write one normalisation call at the top of every public method rather than hand-rolling the same conditional chains in each one.

When combined with Params::Validate::Strict and Return::Set you can formally specify and enforce the input and output contracts of every method.

SYNOPSIS

use Params::Get qw(get_params);
use Params::Validate::Strict;

sub where_am_i {
    my $params = Params::Validate::Strict::validate_strict({
        args   => get_params(undef, \@_),
        schema => {
            latitude  => { type => 'number', min => -90,  max =>  90 },
            longitude => { type => 'number', min => -180, max => 180 },
        },
    });
    printf "You are at %s, %s\n",
        $params->{latitude}, $params->{longitude};
}

where_am_i(latitude => 0.3, longitude => 124);
where_am_i({ latitude => 3.14, longitude => -155 });

METHODS

get_params

Parse the argument list passed to a subroutine and return a unified hash-ref regardless of the calling convention used. Supported conventions:

ARGUMENTS

RETURNS

A hash-ref on success, or undef when $default is undef and no arguments are provided.

SIDE EFFECTS

Croaks from the caller's frame on programming errors (wrong calling convention, non-ARRAY ref passed as $default). Confesses with a full stack trace when $default is defined but zero arguments are received, because that almost always indicates a programming error.

API SPECIFICATION

Input

    {
            default => {
                    type => [ 'string', 'stringref' ],
                    optional => 1,
                    position => 0,
            }, args => {
                    type => [ 'array', 'arrayref' ],
                    optional => 1,
                    position => 1,
            }
    }

output

{
    type => 'hashref',
    optional => 1,
}

MESSAGES

Message                                             Meaning                                Resolution
--------------------------------------------------  -------------------------------------  ----------------------------------------------
::get_params: $default must be a scalar or          A non-ARRAY ref was passed as          Pass a plain string, arrayref of strings,
  arrayref                                          $default                               or undef
Usage: Pkg->method($key => $val)  [stack trace]    $default is defined but no args given  Ensure the caller always passes a value
Usage: Pkg->method()                               Odd-length or unrecognisable arg list  Correct the calling convention in the caller

PSEUDOCODE

1.  Fast-path: if the sole argument is a plain HASH ref, return it
    immediately (fires before $default is inspected -- see LIMITATIONS).

2.  Shift $default.  Validate: must be undef, a plain scalar, or an
    ARRAY ref.  Any other ref type croaks immediately.

3.  If $default is an ARRAY ref, map remaining @_ positionally to those
    key names and return.  A single plain HASH ref is still passed
    through unchanged.

4.  Detect the \@_ calling convention: if exactly one ARRAY ref argument
    remains, check the two-element (key => scalar-val) shorthand and
    return immediately when it matches.  Otherwise unwrap and use the
    array contents as the effective @args.

5.  Dispatch on argument count:
    0 -- confess (with stack trace) if $default is defined;
         return undef otherwise.
    1 -- if $default is defined, wrap the single arg under $default
         (scalar, arrayref, scalarref->deref, coderef, blessed object).
         Without $default: unwrap REF-of-REF, pass HASH ref through,
         return empty ARRAY ref as-is.  Anything else: croak.
    2 with HASH ref as arg[1]
      -- Mandatory-positional + options-hashref pattern.
    even N -- treat as flat key/value pairs.
    odd N  -- croak.

LIMITATIONS

AUTHOR

Nigel Horne, <njh at nigelhorne.com>

BUGS

Please report bugs or feature requests to bug-params-get at rt.cpan.org or through http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Params-Get.

SEE ALSO

SUPPORT

FORMAL SPECIFICATION

get_params

Let D = default key (Str | [Str*] | undef), A = argument tuple.

get_params : D x A* -> HashRef | Undef

-- Fast path (fires before D is inspected -- see LIMITATIONS)
get_params(D, h)            == h             when |A|=1, h:HashRef

-- Positional-names default
get_params([n1..nk], v*)    == {ni -> vi}    i in 1..k, vi = undef when missing

-- Scalar default, single arg
get_params(d, s)            == {d -> s}      d:Str, s:Scalar
get_params(d, a)            == {d -> a}      d:Str, a:ArrayRef
get_params(d, \s)           == {d -> s}      d:Str (scalarref dereferenced)
get_params(d, c)            == {d -> c}      d:Str, c:CodeRef
get_params(d, o)            == {d -> o}      d:Str, o:BlessedObject

-- Mandatory-positional + options-hashref
get_params(d, v, {k->w..})  == {d->v, k->w..}    non-empty opts
get_params(d, d, {k->w..})  == {d -> {k->w..}}   first arg IS the key name

-- Named pairs
get_params(undef, k1,v1..)  == {ki -> vi}    when |A| is even

-- Empty / error
get_params(undef)           == undef
get_params(d)               => confess       d:Str (missing required arg)
get_params(D, odd-list)     => croak

LICENCE AND COPYRIGHT

Copyright 2025-2026 Nigel Horne.

Usage is subject to the GPL2 licence terms. If you use this module, please let me know.