package Venus::Args;
use 5.018;
use strict;
use warnings;
use Venus::Class 'attr', 'base', 'with';
base 'Venus::Kind::Utility';
with 'Venus::Role::Valuable';
with 'Venus::Role::Buildable';
with 'Venus::Role::Accessible';
with 'Venus::Role::Proxyable';
# ATTRIBUTES
attr 'named';
# BUILDERS
sub build_proxy {
my ($self, $package, $method, $value) = @_;
my $has_value = exists $_[3];
return sub {
return $self->get($method) if !$has_value; # no value
return $self->set($method, $value);
};
}
sub build_self {
my ($self, $data) = @_;
$self->named({}) if !$self->named;
return $self;
}
# METHODS
sub assertion {
my ($self) = @_;
my $assert = $self->SUPER::assertion;
$assert->clear->array;
return $assert;
}
sub default {
my ($self) = @_;
return [@ARGV];
}
sub exists {
my ($self, $name) = @_;
return if not defined $name;
my $pos = $self->name($name);
return if not defined $pos;
return CORE::exists $self->indexed->{$pos};
}
sub get {
my ($self, $name) = @_;
return if not defined $name;
my $pos = $self->name($name);
return if not defined $pos;
return $self->indexed->{$pos};
}
sub indexed {
my ($self) = @_;
return {map +($_, $self->value->[$_]), 0..$#{$self->value}};
}
sub name {
my ($self, $name) = @_;
if (defined $self->named->{$name}) {
return $self->named->{$name};
}
if (defined $self->indexed->{$name}) {
return $name;
}
return undef;
}
sub set {
my ($self, $name, $data) = @_;
return if not defined $name;
my $pos = $self->name($name);
return if not defined $pos;
return $self->value->[$pos] = $data;
}
sub unnamed {
my ($self) = @_;
my $list = [];
my $argv = $self->indexed;
my $data = +{reverse %{$self->named}};
for my $index (sort keys %$argv) {
unless (exists $data->{$index}) {
push @$list, $argv->{$index};
}
}
return $list;
}
1;
=head1 NAME
Venus::Args - Args Class
=cut
=head1 ABSTRACT
Args Class for Perl 5
=cut
=head1 SYNOPSIS
package main;
use Venus::Args;
my $args = Venus::Args->new(
named => { flag => 0, command => 1 }, # optional
value => ['--help', 'execute'],
);
# $args->flag; # $ARGV[0]
# $args->get(0); # $ARGV[0]
# $args->get(1); # $ARGV[1]
# $args->action; # $ARGV[1]
# $args->exists(0); # exists $ARGV[0]
# $args->exists('flag'); # exists $ARGV[0]
# $args->get('flag'); # $ARGV[0]
=cut
=head1 DESCRIPTION
This package provides methods for accessing C<@ARGS> items.
=cut
=head1 ATTRIBUTES
This package has the following attributes:
=cut
=head2 named
named(HashRef)
This attribute is read-write, accepts C<(HashRef)> values, is optional, and defaults to C<{}>.
=cut
=head1 INHERITS
This package inherits behaviors from:
L<Venus::Kind::Utility>
=cut
=head1 INTEGRATES
This package integrates behaviors from:
L<Venus::Role::Accessible>
L<Venus::Role::Buildable>
L<Venus::Role::Proxyable>
L<Venus::Role::Valuable>
=cut
=head1 METHODS
This package provides the following methods:
=cut
=head2 default
default() (ArrayRef)
The default method returns the default value, i.e. C<@ARGV>.
I<Since C<0.01>>
=over 4
=item default example 1
# given: synopsis;
my $default = $args->default;
# [@ARGV]
# ["--help", "execute"]
=back
=cut
=head2 exists
exists(Str $key) (Bool)
The exists method returns truthy or falsy if an index or alias value exists.
I<Since C<0.01>>
=over 4
=item exists example 1
# given: synopsis;
my $exists = $args->exists(0);
# 1
=back
=over 4
=item exists example 2
# given: synopsis;
my $exists = $args->exists('flag');
# 1
=back
=over 4
=item exists example 3
# given: synopsis;
my $exists = $args->exists(2);
# undef
=back
=cut
=head2 get
get(Str $key) (Any)
The get method returns the value of the index or alias.
I<Since C<0.01>>
=over 4
=item get example 1
# given: synopsis;
my $get = $args->get(0);
# "--help"
=back
=over 4
=item get example 2
# given: synopsis;
my $get = $args->get('flag');
# "--help"
=back
=over 4
=item get example 3
# given: synopsis;
my $get = $args->get(2);
# undef
=back
=cut
=head2 indexed
indexed() (HashRef)
The indexed method returns a set of indices and values.
I<Since C<0.01>>
=over 4
=item indexed example 1
# given: synopsis;
my $indexed = $args->indexed;
# { "0" => "--help", "1" => "execute" }
=back
=cut
=head2 name
name(Str $key) (Str | Undef)
The name method resolves and returns the index for an index or alias, and
returns undefined if not found.
I<Since C<0.01>>
=over 4
=item name example 1
# given: synopsis;
my $name = $args->name('flag');
=back
=cut
=head2 set
set(Str $key, Any $data) (Any)
The set method sets and returns the value of an index or alias.
I<Since C<0.01>>
=over 4
=item set example 1
# given: synopsis;
my $set = $args->set(0, '-?');
# "-?"
=back
=over 4
=item set example 2
# given: synopsis;
my $set = $args->set('flag', '-?');
# "-?"
=back
=over 4
=item set example 3
# given: synopsis;
my $set = $args->set('verbose', 1);
# undef
=back
=cut
=head2 unnamed
unnamed() (ArrayRef)
The unnamed method returns a list of unaliases indices.
I<Since C<0.01>>
=over 4
=item unnamed example 1
package main;
use Venus::Args;
my $args = Venus::Args->new(
named => { flag => 0, command => 1 },
value => ['--help', 'execute', '--format', 'markdown'],
);
my $unnamed = $args->unnamed;
# ["--format", "markdown"]
=back
=over 4
=item unnamed example 2
package main;
use Venus::Args;
my $args = Venus::Args->new(
named => { command => 1 },
value => ['execute', 'phase-1', '--format', 'markdown'],
);
my $unnamed = $args->unnamed;
# ["execute", "--format", "markdown"]
=back
=cut