Return-Value

 view release on metacpan or  search on metacpan

lib/Return/Value.pm  view on Meta::CPAN

#pod
#pod =head2 Attributes
#pod
#pod All return values have a set of attributes that package up the information
#pod returned.  All attributes can be accessed or changed via methods of the same
#pod name, unless otherwise noted.  Many can also be accessed via overloaded
#pod operations on the object, as noted below.
#pod
#pod =over 4
#pod
#pod =item type
#pod
#pod A value's type is either "success" or "failure" and (obviously) reflects
#pod whether the value is returning success or failure.
#pod
#pod =item errno
#pod
#pod The errno attribute stores the error number of the return value.  For
#pod success-type results, it is by default undefined.  For other results, it
#pod defaults to 1.
#pod
#pod =item string
#pod
#pod The value's string attribute is a simple message describing the value.
#pod
#pod =item data
#pod
#pod The data attribute stores a reference to a hash or array, and can be used as a
#pod simple way to return extra data.  Data stored in the data attribute can be
#pod accessed by dereferencing the return value itself.  (See below.)
#pod
#pod =item prop
#pod
#pod The most generic attribute of all, prop is a hashref that can be used to pass
#pod an arbitrary number of data structures, just like the data attribute.  Unlike
#pod the data attribute, though, these structures must be retrieved via method calls.
#pod
#pod =back
#pod
#pod =head1 FUNCTIONS
#pod
#pod The functional interface is highly recommended for use within functions
#pod that are using C<Return::Value> for return values.  It's simple and
#pod straightforward, and builds the entire return value in one statement.
#pod
#pod =over 4
#pod
#pod =cut

# This hack probably impacts performance more than I'd like to know, but it's
# needed to have a hashref object that can deref into a different hash.
# _ah($self,$key, [$value) sets or returns the value for the given key on the
# $self blessed-ref

sub _ah {
    my ($self, $key, $value) = @_;
    my $class = ref $self;
    bless $self => "ain't::overloaded";
    $self->{$key} = $value if @_ > 2;
    my $return = $self->{$key};
    bless $self => $class;
    return $return;
}

sub _builder {
    my %args = (type => shift);
    $args{string} = shift if (@_ % 2);
    %args = (%args, @_);

    $args{string} = $args{type} unless defined $args{string};

    $args{errno}  = ($args{type} eq 'success' ? undef : 1)
        unless defined $args{errno};

    __PACKAGE__->new(%args);
}

#pod =item success
#pod
#pod The C<success> function returns a C<Return::Value> with the type "success".
#pod
#pod Additional named parameters may be passed to set the returned object's
#pod attributes.  The first, optional, parameter is the string attribute and does
#pod not need to be named.  All other parameters must be passed by name.
#pod
#pod  # simplest possible case
#pod  return success;
#pod
#pod =cut

sub success { _builder('success', @_) }

#pod =pod
#pod
#pod =item failure
#pod
#pod C<failure> is identical to C<success>, but returns an object with the type
#pod "failure"
#pod
#pod =cut

sub failure { _builder('failure', @_) }

#pod =pod
#pod
#pod =back
#pod
#pod =head1 METHODS
#pod
#pod The object API is useful in code that is catching C<Return::Value> objects.
#pod
#pod =over 4
#pod
#pod =item new
#pod
#pod   my $return = Return::Value->new(
#pod       type   => 'failure',
#pod       string => "YOU FAIL",
#pod       prop   => {
#pod           failed_objects => \@objects,
#pod       },
#pod   );
#pod
#pod Creates a new C<Return::Value> object.  Named parameters can be used to set the
#pod object's attributes.
#pod
#pod =cut

sub new {
    my $class = shift;
    bless { type => 'failure', string => q{}, prop => {}, @_ } => $class;
}

#pod =pod
#pod
#pod =item bool
#pod
#pod   print "it worked" if $result->bool;
#pod
#pod Returns the result in boolean context: true for success, false for failure.
#pod
#pod =item prop
#pod
#pod   printf "%s: %s',
#pod     $result->string, join ' ', @{$result->prop('strings')}
#pod       unless $result->bool;
#pod
#pod Returns the return value's properties. Accepts the name of
#pod a property returned, or returns the properties hash reference
#pod if given no name.
#pod
#pod =item other attribute accessors
#pod
#pod Simple accessors exist for the object's other attributes: C<type>, C<errno>,
#pod C<string>, and C<data>.
#pod
#pod =cut

sub bool { _ah($_[0],'type') eq 'success' ? 1 : 0 }

sub type {
    my ($self, $value) = @_;
    return _ah($self, 'type') unless @_ > 1;
    Carp::croak "invalid result type: $value"
        unless $value eq 'success' or $value eq 'failure';
    return _ah($self, 'type', $value);
};

foreach my $name ( qw[errno string data] ) {
    ## no critic (ProhibitNoStrict)
    no strict 'refs';
    *{$name} = sub {
        my ($self, $value) = @_;
        return _ah($self, $name) unless @_ > 1;
        return _ah($self, $name, $value);
    };
}

sub prop {
    my ($self, $name, $value) = @_;
    return _ah($self, 'prop')          unless $name;
    return _ah($self, 'prop')->{$name} unless @_ > 2;
    return _ah($self, 'prop')->{$name} = $value;
}

#pod =pod
#pod
#pod =back
#pod
#pod =head2 Overloading
#pod



( run in 2.759 seconds using v1.01-cache-2.11-cpan-99c4e6809bf )