package Venus::Role::Stashable;

use 5.018;

use strict;
use warnings;

use Moo::Role;

# BUILDERS

sub BUILD {
  return $_[0];
}

# MODIFIERS

around BUILD => sub {
  my ($orig, $self, $args) = @_;

  $self->$orig($args);

  $self->{'$stash'} = delete $args->{'$stash'} || {} if !$self->{'$stash'};

  return $self;
};

# METHODS

sub stash {
  my ($self, $key, $value) = @_;

  return $self->{'$stash'} if !exists $_[1];

  return $self->{'$stash'}->{$key} if !exists $_[2];

  $self->{'$stash'}->{$key} = $value;

  return $value;
}

1;



=head1 NAME

Venus::Role::Stashable - Stashable Role

=cut

=head1 ABSTRACT

Stashable Role for Perl 5

=cut

=head1 SYNOPSIS

  package Example;

  use Venus::Class;

  with 'Venus::Role::Stashable';

  has 'test';

  package main;

  my $example = Example->new(test => time);

  # $example->stash;

=cut

=head1 DESCRIPTION

This package modifies the consuming package and provides methods for stashing
data within the object.

=cut

=head1 METHODS

This package provides the following methods:

=cut

=head2 stash

  stash(Any $key, Any $value) (Any)

The stash method is used to fetch and stash named values associated with the
object. Calling this method without arguments returns all values.

I<Since C<0.01>>

=over 4

=item stash example 1

  package main;

  my $example = Example->new(test => time);

  my $stash = $example->stash;

  # {}

=back

=over 4

=item stash example 2

  package main;

  my $example = Example->new(test => time);

  my $stash = $example->stash('test', {1..4});

  # { 1 => 2, 3 => 4 }

=back

=over 4

=item stash example 3

  package main;

  my $example = Example->new(test => time);

  my $stash = $example->stash('test');

  # undef

=back

=cut

=head1 AUTHORS

Cpanery, C<cpanery@cpan.org>

=cut

=head1 LICENSE

Copyright (C) 2021, Cpanery

Read the L<"license"|https://github.com/cpanery/venus/blob/master/LICENSE> file.

=cut