package Venus::Kind::Value;
use 5.018;
use strict;
use warnings;
use overload (
'""' => 'explain',
'~~' => 'explain',
fallback => 1,
);
use Venus::Class 'base', 'with';
base 'Venus::Kind';
with 'Venus::Role::Valuable';
with 'Venus::Role::Buildable';
with 'Venus::Role::Accessible';
with 'Venus::Role::Explainable';
with 'Venus::Role::Proxyable';
with 'Venus::Role::Pluggable';
# BUILDERS
sub build_arg {
my ($self, $data) = @_;
return {
value => $data,
};
}
# METHODS
sub cast {
my ($self, @args) = @_;
require Venus::Type;
my $value = $self->can('value') ? $self->value : $self;
return Venus::Type->new(value => $value)->cast(@args);
}
sub defined {
my ($self) = @_;
return CORE::defined($self->get) ? true : false;
}
sub explain {
my ($self) = @_;
return $self->get;
}
sub mutate {
my ($self, $code, @args) = @_;
return $self->set($self->assert($self->coerce($self->$code(@args))));
}
sub TO_JSON {
my ($self) = @_;
return $self->get;
}
1;
=head1 NAME
Venus::Kind::Value - Value Base Class
=cut
=head1 ABSTRACT
Value Base Class for Perl 5
=cut
=head1 SYNOPSIS
package Example;
use Venus::Class;
base 'Venus::Kind::Value';
sub test {
$_[0]->get + 1
}
package main;
my $example = Example->new(1);
# $example->defined;
=cut
=head1 DESCRIPTION
This package provides identity and methods common across all L<Venus> value
classes.
=cut
=head1 INHERITS
This package inherits behaviors from:
L<Venus::Kind>
=cut
=head1 INTEGRATES
This package integrates behaviors from:
L<Venus::Role::Accessible>
L<Venus::Role::Buildable>
L<Venus::Role::Explainable>
L<Venus::Role::Pluggable>
L<Venus::Role::Proxyable>
L<Venus::Role::Valuable>
=cut
=head1 METHODS
This package provides the following methods:
=cut
=head2 cast
cast(Str $kind) (Object | Undef)
The cast method converts L<"value"|Venus::Kind::Value> objects between
different I<"value"> object types, based on the name of the type provided. This
method will return C<undef> if the invocant is not a L<Venus::Kind::Value>.
I<Since C<0.08>>
=over 4
=item cast example 1
package main;
my $example = Example->new;
my $cast = $example->cast;
# bless({value => undef}, "Venus::Undef")
=back
=over 4
=item cast example 2
package main;
my $example = Example->new(
value => 123.45,
);
my $cast = $example->cast('array');
# bless({value => [123.45]}, "Venus::Array")
=back
=over 4
=item cast example 3
package main;
my $example = Example->new(
value => 123.45,
);
my $cast = $example->cast('hash');
# bless({value => {'123.45' => 123.45}, "Venus::Hash")
=back
=cut
=head2 defined
defined() (Int)
The defined method returns truthy or falsy if the underlying value is
L</defined>.
I<Since C<0.01>>
=over 4
=item defined example 1
package main;
my $example = Example->new;
my $defined = $example->defined;
# 0
=back
=over 4
=item defined example 2
package main;
my $example = Example->new(time);
my $defined = $example->defined;
# 1
=back
=cut
=head2 explain
explain() (Any)
The explain method returns the value set and is used in stringification
operations.
I<Since C<0.01>>
=over 4
=item explain example 1
package main;
my $example = Example->new('hello, there');
my $explain = $example->explain;
# "hello, there"
=back
=cut
=head2 mutate
mutate(Str | CodeRef $code, Any @args) (Object)
The mutate method dispatches the method call or executes the callback and
returns the result, which if is of the same type as the invocant's underlying
data type will update the object's internal state or will throw an exception.
I<Since C<1.23>>
=over 4
=item mutate example 1
# given: synopsis
package main;
$example->mutate('test');
$example;
# bless({value => 2}, "Example")
=back
=cut