App::Y...:Option(3pm)
π App::Yath::Option(3pm) π
okay bestie, welcome to the yath option bible, part one of three, buckle up π
β¨ NAME β¨
App::Yath::Option β it's literally the representation of a yath option. that's the whole job. π«Ά
πΈ DESCRIPTION πΈ
So this class π¦ represents one single command line option for yath. like, just one. one flag, one job, main character energy. no cap.
π¦ SYNOPSIS π¦
ngl you usually will not be creating option instances directly, bestie. like, why would you. normally you use App::Yath::Options which gives you sugar π and makes sure your options actually land in the right place. iykyk.
use App::Yath::Options;
# You can specify a single option:
option color => (
prefix => 'display',
category => "Display Options",
description => "Turn color on, default is true if STDOUT is a TTY.",
default => sub { -t STDOUT ? 1 : 0 },
);
# If you are specifying multiple options you can use an option_group to
# define common parameters.
option_group {prefix => 'display', category => "Display Options"} => sub {
option color => (
description => "Turn color on, default is true if STDOUT is a TTY.",
default => sub { -t STDOUT ? 1 : 0 },
);
option verbose => (
short => 'v',
type => 'c',
description => "Be more verbose",
default => 0,
);
};
π ATTRIBUTES π
these can be handed over at object construction time, or they get generated internally by the machinery. either way, slay.
π§ CONSTRUCTION ONLY
applicable => sub { ... }β this callback is what theapplicable()method uses. you feed it a coderef and it decides if the option is even applicable. π
option foo => (
...,
applicable => sub {
my ($opt, $options) = @_;
...
return $bool;
},
);
π READ-ONLY
these ones you just read, you don't write them, periodt.
β REQUIRED
$class->new(prefix => 'my_prefix')$scalar = $opt->prefix()
a prefix is required, no exceptions bestie. every option has its value inserted into the settings structure, which is an instance of Test2::Harness::Settings. the shape is "$settings->PREFIX->OPTION".
if you don't give a "name" attribute, the default name ends up being "PREFIX-TITLE". and the name is the actual command line argument, so the default name means the flag is --PREFIX-TITLE. iconic.
$class->new(type => $type)$type = $opt->type()
every option needs a type. if you don't say anything, the default is 'b', a.k.a. boolean.
here's every possible type, plus its aliases. you can use the type character or any of the aliases to say which one you want:
bboolbooleanβ true or false values, will be normalized to0or1in most cases.ccountcountercountingβ a counter, starts at0and then increments every single time the option is used. π―sscalarstringnumberβ needs an argument, and that argument is treated as a scalar value. no type checking happens in the option itself, though you can check it yourself using"action"or"normalize"callbacks, which are documented under those attributes.mmultimultiplelistarrayβ needs an argument treated as a scalar value, and you can use it multiple times. all the arguments you hand over get appended to an array. πddefdefaultβ argument is optional, scalar when it is provided. use--opt=argto provide an argument β--opt argwill not work,arggets seen as its own separate item on the command line. you can also use it with no arg at all (--opt) to signal that a default argument should be used (set via the"action"callback β not the"default"attribute, which is a default value regardless of whether the option is used at all).
real world example from the debug options (simplified for doc purposes, don't @ me):
option summary => (
type => 'd',
description => "Write out a summary json file, if no path is provided 'summary.json' will be used. The .json extension is added automatically if omitted.",
long_examples => ['', '=/path/to/summary.json'],
# New way to specify an auto-fill value for when no =VAL is provided.
# If you do not specify this the default autofill is '1' for legacy support.
autofill => 'VALUE',
# Old way to autofill a value (default is 1 for auto-fill)
# Using autofill is significantly better.
# You can also use action for additional behavior along with autofill,
# but the default will be your auto-fill value, not '1'.
action => sub {
my ($prefix, $field, $raw, $norm, $slot, $settings) = @_;
# $norm will be '1' if option was used without an argument, so we
# just use the provided value when it is not 1'.
return $$slot = $norm unless $norm eq '1';
# $norm was 1, so this is our no-arg "default" behavior
# Do nothing if a value is already set
return if $$slot;
# Set the default value of 'summary.json'
return $$slot = 'summary.json';
},
);
};
Dmulti-defmultiple-defaultlist-defaultarray-defaultβ this is"d"and"m"combined into one glorious thing. you can use the option multiple times to list multiple values, and you can call it with no args to add a set of "default" values. (not to be confused with THEdefaultattribute, which is used even if the option never shows up on the command line, bestie, they are NOT the same thing π)
real world example (simplified for doc purposes):
option dev_libs => (
type => 'D',
short => 'D',
name => 'dev-lib',
category => 'Developer',
description => 'Add paths to @INC before loading ANYTHING. This is what you use if you are developing yath or yath plugins to make sure the yath script finds the local code instead of the installed versions of the same code. You can provide an argument (-Dfoo) to provide a custom path, or you can just use -D without and arg to add lib, blib/lib and blib/arch.',
long_examples => ['', '=lib'],
short_examples => ['', '=lib', 'lib'],
# New way to specify the auto-fill values. This may be a single scalar,
# or an arrayref.
autofill => [ 'lib', 'blib/lib', 'blib/arch' ],
# Old way to specify the auto-fill values.
action => sub {
my ($prefix, $field, $raw, $norm, $slot, $settings) = @_;
# If no argument was provided use the 'lib', 'blib/lib', and 'blib/arch' defaults.
# If an argument was provided, use it.
push @{$$slot} => ($norm eq '1') ? ('lib', 'blib/lib', 'blib/arch') : ($norm);
},
);
hhashβ the hash type. every time the option is used it adds a single key/value pair to the hash, and you split the key from the value with an=sign. the option can be used multiple times, and a value is required. π
yath --opt foo=bar --opt baz=bat
Hhash-listβ basically the'h'type, except the value for the key/value pair is expected to be a comma separated list, and it gets slotted under the key as an arrayref.
yath --opt foo=a,b,c --opt bar=1,2,3
that yath command above would produce this structure β¨:
{
foo => ['a', 'b', 'c'],
bar => ['1', '2', '3'],
}
$class->new(title => 'my_title')$title = $opt->title()
you MUST specify either a title, or BOTH a name and a field. if you only give a title, that title is used to generate both the name and the field. πͺ
so if your title is 'foo-bar_baz', your field becomes 'foo_bar_baz' and your name becomes '$PREFIX-foo-bar-baz'.
basically the title is what generates a sane field and/or name if neither one is specified. for the field, all dashes get changed to underscores, and the field is used as the key in the settings: "$settings->prefix->field". for the name, all underscores get changed to dashes, and if the option comes from a plugin then 'prefix-' gets prepended too. the name is what makes the command line argument --name.
if you don't want or don't like the name and field auto-generated from a title, just specify a name or a title directly, bestie. you're in charge. π
$class->new(name => 'my-name')$name = $opt->name()
you MUST specify either a title, or BOTH a name and field. if you only give a title, it generates the name and the field for you.
this name is your primary command line argument. if your name is "foo", your command line argument is --foo.
$class->new(field => 'my_field')$field = $opt->field()
you MUST specify either a title, or BOTH a name and field. if you only give a title, it generates the name and the field for you.
the field is what's used in the settings hash. if your field is "foo", your settings path is "$setting->prefix->foo".
π OPTIONAL
$class->new(action => sub ...)$coderef = $opt->action()
option foo => (
...,
action => sub {
my ($prefix, $field_name, $raw_value, $normalized_value, $slot_ref, $settings, $handler, $options) = @_;
# If no action is specified the following is all that is normally
# done. Having an action means this is not done, so if you want the
# value stored you must call this or similar.
$handler->($slot, $normalized_value);
},
);
so here's what all those args are π
$prefixβ the prefix for the option, the one you specified when you defined the option.$field_nameβ the field for the option, the one you specified when you defined the option.$raw_valueβ the value/argument that showed up on the command line."--foo bar"would give us"bar". this is BEFORE any processing or normalizing happens, fr fr.
for options that don't take arguments, or where arguments are optional and none were provided, this will be '1'.
$normalized_valueβ if a normalize callback was provided, this is what you get after running$raw_valuethrough that normalize callback.$slot_refβ this is a scalar reference to the settings slot that holds the option value(s). π«Ά
the default behavior when no action is specified is usually one of these:
$$slot_ref = $normalized_value;
push @{$$slot_ref} => $normalized_value;
However, to save yourself trouble you can use the $handler instead (see below).
$settingsβ theTest2::Harness::Settingsinstance. That's the actual settings object, bestie. π$handlerβ a callback that "does the right thing" as far as setting the value in the settings hash. This is literally what gets used when you don't set an action callback.
$handler->($slot, $normalized_value);
$optionsβ theApp::Yath::Optionsinstance this option belongs to. Mainly useful if you've got an option that might add even more options (like how the--pluginoption does it). Heads up though: if you go down that road you should also set theadds_optionsattribute to true. Skip that and the options list won't get refreshed, so your brand new options might not show up at all. π
β¨ $class->new(adds_options => $bool) and $bool = $opt->adds_options()
If this is true, it means using this option could unlock more options. Example: loading a plugin. π
β¨ $class->new(alt => ['alt1', 'alt2', ...]) and $arrayref = $opt->alt()
Give your option alternative names. These are aliases that do the exact same thing on the command line β mainly a backcompat move for when an option gets renamed. π
β¨ $class->new(builds => 'My::Class') and $my_class = $opt->builds()
Use this when your option is part of constructing another object (like when the group it belongs to is made of options that map 1-to-1 onto fields in another object being built). The ultimate effect: an exception gets thrown if that class doesn't have the right attribute. Think of it as a safety net πΈοΈ so you catch errors early when field names change, or when they're missing between this representation and the object being composed.
β¨ $class->new(category => 'My Category') and $category = $opt->category()
This is what sorts/displays the help and POD documentation for your option. Leave it out and it gets set to 'NO CATEGORY - FIX ME'. The default is basically there so everyone knows you don't know what you're doing :-). π
β¨ $class->new(clear_env_vars => $bool) and $bool = $opt->clear_env_vars()
This one only does anything when it's paired up with the env_vars attribute.
Example:
option foo => (
...
env_vars => ['foo', 'bar', 'baz'],
clear_env_vars => 1,
):
So in this case you're saying option foo can be set from the value of $ENV{foo}, $ENV{bar}, or $ENV{baz} vars if any of them are defined. Then clear_env_vars tells it to delete those environment variables after they've been used to set the option. Super useful if you want the env var to set an option but you do not want any tests to be able to see that env var once it's been used. π§Ό
β¨ $class->new(default => $scalar) / $class->new(default => sub { return $default }) and $scalar_or_coderef = $opt->default()
Sets a default value for the field in the settings hash. Important: the default is set before any command line processing happens, so if the option never shows up on the command line, the default value is just... there. π
Make sure you use the correct default value for your type. A scalar for 's', an arrayref for 'm', etc.
Note: for any non-scalar type you wanna use a subref to define the value:
option foo => (
...
type => 'm',
default => sub { [qw/a b c/] },
);
β¨ $class->new(description => "Fe Fi Fo Fum") and $multiline_string = $opt->description()
Description of your option. It shows up in help output and POD. If you don't provide a value the default is 'NO DESCRIPTION - FIX ME'. π
β¨ $class->new(env_vars => \@LIST) and $arrayref = $opt->env_vars()
If set, this should be an arrayref of environment variable names. If any of those environment variables are defined, then the settings get updated exactly as though the option had been provided on the command line with that value. β¨
Example:
option foo => (
prefix => 'blah',
type => 's',
env_vars => ['FOO', 'BAR'],
);
Then this command line:
FOO="xxx" yath test
should be the same as
yath test --foo "xxx"
You can also ask to have the environment variables cleared once they've been checked:
option foo => (
prefix => 'blah',
type => 's',
env_vars => ['FOO', 'BAR'],
clear_env_vars => 1, # This tells yath to clear the env vars after they
are used.
);
And if you'd like the option set to the opposite of the environment variable, you can prefix it with a '!' character:
option foo =>(
...
env_vars => ['!FOO'],
);
In that case these two are equivalent:
FOO=0 yath test
yath test --foo=1
Careful though β this only works when the variable is defined. If $ENV{FOO} isn't defined, then the variable is not used. Periodt. π«Ά
β¨ $class->new(from_command => 'App::Yath::Command::COMMAND') and $cmd_class = $opt->from_command()
If your option was defined for a specific command, this gets set. You don't normally set this yourself β the tools in App::Yath::Options handle that for you. π οΈ
β¨ $class->new(from_plugin => 'App::Yath::Plugin::PLUGIN') and $plugin_class = $opt->from_plugin()
If your option was defined for a specific plugin, this gets set. Again, you don't normally set this yourself β the tools in App::Yath::Options handle it for you. π οΈ
β¨ $class->new(long_examples => [' foo', '=bar', ...]) and $arrayref = $opt->long_examples()
Just for documentation purposes. If your option takes arguments, you can drop examples here. The examples should not include the option itself β so "--foo bar" would be wrong, you should just do " bar". π
β¨ $class->new(negate => sub { ... }) and $coderef = $opt->negate()
Want a custom handler for negation (--no-OPT)? Provide one right here.
option foo => (
...
negate => sub {
my ($prefix, $field, $slot, $settings, $options) = @_;
...
},
);
The variables are the same ones as in the action callback.
β¨ $class->new(normalize => sub { ... }) and $coderef = $opt->normalize()
The normalize attribute holds a callback sub that takes the raw value as input and returns the normalized form. πͺ
option foo => (
...,
normalize => sub {
my $raw = shift;
...
return $norm;
},
);
β¨ $class->new(pre_command => $bool) and $bool = $opt->pre_command()
Options are either command-specific, or pre-command. Pre-command options are ones yath processes even if it hasn't figured out what command is being used yet. Great examples are --dev-lib and --plugin. π
yath --pre-command-opt COMMAND --command-opt
Most of the time this should be false β very few options qualify as pre-command.
β¨ $class->new(pre_process => sub { ... }) and $coderef = $opt->pre_process()
This is essentially a BEGIN block for options. This callback fires as soon as the option is parsed from the command line β well before the value gets normalized and added to settings. A great use for this: when your option needs to inject additional App::Yath::Option instances into the App::Yath::Options instance. π
option foo => (
...
pre_process => sub {
my %params = @_;
my $opt = $params{opt};
my $options = $params{options};
my $action = $params{action};
my $type = $params{type};
my $val = $params{val};
...;
},
);
Explanation of parameters:
$params{opt}β the opt instance.$params{options}β theApp::Yath::Optionsinstance.$params{action}β a string, usually either"handle"or"handle_negation".$params{type}β a string, usually"pre-command"or"command ($CLASS)", where the second one has the command package in the parentheses.$params{val}β the value being set, if any. For options that don't take arguments, or in the case of negation, this key may not exist at all. π«₯
β¨ $class->new(short => $single_character_string) and $single_character_string = $opt->short()
Want your option to be usable as a short option (single character, single dash -X)? Provide the character you wanna use right here. If the option doesn't require an argument, it can be combined with other no-argument short options β -xyz would be equivalent to -x -y -z. π
There are only so many single characters to go around, so options are restricted to picking only 1.
Please note: Yath reserves the right to add any single-character short options in the main distribution. If they conflict with third party plugins/commands, then the third party must adapt and change its options. Because of that, it is not recommended to use any short options in third party addons. π¨
β¨ $class->new(short_examples => [' foo', ...]) and $arrayref = $opt->short_examples()
Just for documentation purposes. If your option takes arguments, you can drop examples here. The examples should not include the option itself β so "-f bar" would be wrong, you should just do " bar". π
This attribute is not used if you don't provide a short attribute.
β¨ $class->new(trace => [$package, $file, $line]) and $arrayref = $opt->trace()
This is almost always auto-populated for you via caller(). It should be an arrayref with a package, filename and line number. This is what gets used if there's a conflict between parameter names and/or short options. If that kind of situation ever comes up, the file/line number of all the conflicting options gets reported so it can be fixed. π
π METHODS π
okay bestie, this is the good part β all the stuff the object can do. every one of these is a method you call on your $opt object, and we're going through them one by one, no skips, no shortcuts π«Ά
$bool = $opt->allows_arg()β returns true if args can be given to the option (it depends on the type, periodt). important nuance incoming: this being true does NOT mean the option must take an argument.'D'type options can accept arguments, but they can also be used with no arguments at all. it's giving "flexible icon" π$bool = $opt->applicable($options)β if the option has an applicability callback set up, this runs it to figure out whether the option is even applicable given thatApp::Yath::Optionsinstance. if no callback was provided, it just returns true, no drama π$character = $opt->canon_type($type_name)β hand it a long alias for an option type and it gives you back the single-character canonical name. heads up: it returnsundeffor any unknown strings. and the way it's not translating single-character names to themselves?? so$opt->canon_type('s')returnsundef, while$opt->canon_type('string')returns's'. yeah. that's the vibe. iykyk π$val = $opt->get_default()β gives you the proper default value for the option. if a custom default was set, that's what you get; otherwise it falls back to the correct generic default for that option's type.
here's a snippet showing the defaults for the types:
# First check env vars and return any values from there
...
# Then check for a custom default and use it.
...
return 0
if $self->{+TYPE} eq 'c'
|| $self->{+TYPE} eq 'b';
return []
if $self->{+TYPE} eq 'm'
|| $self->{+TYPE} eq 'D';
return {}
if $self->{+TYPE} eq 'h'
|| $self->{+TYPE} eq 'H';
# All others get undef
return undef;
$val $opt->get_normalized($raw)β converts a raw value into a normalized one. if a custom"normalize"attribute was set, that gets used; otherwise it normalizes according to the type. this is literally where booleans become0or1, hashes get split, hash-lists get split even further, etc. β¨$opt->handle($raw, $settings, $options, $list)β this method handles setting the value in$settings. lowkey a warning: you should not normally need to call this yourself. leave it to the machine bestie π$opt->handle_negation()β this method handles a negated option. same deal as above: you should not normally need to call this yourself π@list = $opt->long_args()β returns the name plus any aliases. boom, list acquired π$ref = $opt->option_slot($settings)β gets you thesettings->prefix->fieldreference. it creates the setting field if it's not already there, so it's not me being extra, it's just doing its job π$bool = $opt->requires_arg()β returns true if this option requires an argument when it's used. no argument, no peace.$string = $opt->trace_string()β returns a string like"somefile.pm line 42"based on where the option was defined. cute little receipt of where it came from π§Ύ$bool = $opt->valid_type($character)β checks whether a single character type is valid. simple, clean, iconic.
π DOCUMENTATION GENERATION π
yeah the options can generate their own docs, main character energy fr π
$string = $opt->cli_docs()β gives you the option documentation in a format that works for the"yath help COMMAND"command.$string = $opt->pod_docs()β gives you the option documentation in POD format, like so:
=item ....
.. option details ...
π SOURCE π
the source code repository for Test2-Harness lives at http://github.com/Test-More/Test2-Harness/. go peek, bestie, it's right there π«Ά
π MAINTAINERS π
Chad Granum <exodist@cpan.org>
β AUTHORS β
Chad Granum <exodist@cpan.org>
π COPYRIGHT π
Copyright 2020 Chad Granum <exodist7@gmail.com>.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
See http://dev.perl.org/licenses/
and that's a wrap on the whole page, bestie!! π this was perl v5.40.1, dated 2026-05-10, and honestly? iconic of her. go forth and option responsibly π
β¨πΈ
π¦ where this page comes from
- ubuntu stonking: libtest2-harness-perl 1.000172-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms