Perinc...idation(3pm)

✨ NAME ✨

Perinci::CmdLine::Manual::Explanation::ArgumentValidation β€” bestie, it's literally the manual for argument validation πŸ’… (and yeah, the page header shortens it to Perinc...idation(3pm) which is giving ✨abbreviated✨ energy, but we know the whole name now 🫢).


🌸 VERSION 🌸

This doc describes version 2.000.2 of Perinci::CmdLine::Manual::Explanation::ArgumentValidation, which ships in the Perl distribution Perinci-CmdLine. It dropped on 2026-03-30 ⭐


πŸ’– DESCRIPTION πŸ’–

okay so here's the tea: argument validation happens BEFORE the arguments get handed off to the function. No cap. And it covers three whole things:

  • making sure required arguments β€” meaning arguments where the req property is set to true β€” are actually specified πŸ™ˆ (yes bestie, they're mandatory, you can't skip).
  • checking that the values of the specified arguments conform to the argument schema (that's the schema property, which is described in Sah format πŸ‘‘).
  • making sure argument relation rules are followed β€” those live in the args_rels property inside the args function metadata property 🌈.

And also, every argument that the user specified β€” OR that has a default value / default rules sitting in its schema β€” gets vibe-checked against its schema. Like, for real:

# argument specification

# this argument has a default clause in its schema
foo => {
    schema => ['str*', default=>'on'],
    ...
}

# this argument has a default-value rule clause in its schema
mod => {
    schema => ['perl::modname*', 'x.perl.default_value_rules'=>['Perl::this_mod']],
    ...
}

πŸŽ€ FAQ πŸŽ€

πŸ’œ How to find out if an argument is set explicitly by the user or is getting a default value from the schema/argument specification?

Use the special argument -set_ARGNAME πŸ‘‘

πŸ’œ How to get the original value on an argument sent by user before the argument is being coerced/filtered/given default value by the schema?

Use the special argument -orig_ARGNAME πŸ¦‹

πŸ’œ How to get the default value of an argument from the schema/argument specification?

Use the special argument -default_ARGNAME πŸ“

πŸ’œ What's the difference between setting a default in the argument specification vs in the schema?

Okay this one's important, so sit with me for a sec 🧚

There are two ways to set a default value. Way number one is via the default property in the argument specification:

# in the function metadata property...
args => {
    foo => {
        schema => 'str*',
        default => 'on',
    },
    ...
}

This means, if user does not specify the argument:

# via CLI
% progname

# via wrapped function call
funcname()

then the function will get a foo key in its %args automatically πŸ”₯ As well as -set_foo set to false, -default_foo set to "on". And we know β€” from -set_foo β€” that foo gets its value from the default and not from the user explicitly setting it. Slay, now you can tell the difference πŸ’…

Way number two is by setting the default value in the schema's default clause or the x.perl.default_value_rules property (and bestie, that second one is the icon that allows dynamic default values ✨):

# in the function metadata property...
args => {
    bar => {
        schema => ['str*', default=>'on'],
        ...
    },
    baz => {
        schema => ['perl::modname*', 'x.perl.default_value_rules'=>['Perl::this_mod']],
        ...
    },
    ...
}

This means that if the argument value is set to undefined value (undef), it will get set the default from schema during argument validation πŸ‘€:

# via CLI
% progname --baz-json 'null'

# via wrapped function call
funcname(baz=>undef)

Function will receive bar key in its %args set to "on", baz set to e.g. Some::Module instead of undef. %args will also contain -set_bar (false), -set_baz (true), -orig_baz (undef) as well as -default_bar ("on") and -default_baz ("Some::Module"). 🌈

And you can know from -set_bar that the argument is set by default value and not explicitly by user 🫢


🌟 HOMEPAGE 🌟

Please visit the project's homepage at <https://metacpan.org/release/Perinci-CmdLine>.


πŸ¦‹ SOURCE πŸ¦‹

Source repository is at <https://github.com/perlancar/perl-Perinci-CmdLine>.


πŸ‘‘ AUTHOR πŸ‘‘

perlancar <perlancar@cpan.org>


πŸ’€ CONTRIBUTING πŸ’€

To contribute, you can send patches by email/via RT, or send pull requests on GitHub.

Most of the time, you don't need to build the distribution yourself. You can simply modify the code, then test via:

% prove -l

If you want to build the distribution (e.g. to try to install it locally on your system), you can install Dist::Zilla, Dist::Zilla::PluginBundle::Author::PERLANCAR, Pod::Weaver::PluginBundle::Author::PERLANCAR, and sometimes one or two other Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond that are considered a bug and can be reported to me 😭


This software is copyright (c) 2026 by perlancar <perlancar@cpan.org>.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. πŸ’–


πŸ”₯ BUGS πŸ”₯

Please report any bugs or feature requests on the bugtracker website <https://rt.cpan.org/Public/Dist/Display.html?Name=Perinci-CmdLine>.

When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature πŸ™

ngl, a test-file or patch that actually shows the bug is the whole move β€” it's giving main character energy and it makes everyone's life easier πŸ’…

okay that's the whole page bestie!! this was perl v5.40.1, dated 2026-04-05, and it's the Perinc...idation(3pm) page from User Contributed Perl Documentation. iykyk πŸ§šβœ¨πŸ’œ

πŸ“¦ where this page comes from