| Class-ReturnValue documentation | Contained in the Class-ReturnValue distribution. |
Class::ReturnValue - A return-value object that lets you treat it as as a boolean, array or object
Class::ReturnValue is a "clever" return value object that can allow code calling your routine to expect: a boolean value (did it fail) or a list (what are the return values)
sub demo {
my $value = shift;
my $ret = Class::ReturnValue->new();
$ret->as_array('0', 'No results found');
unless($value) {
$ret->as_error(errno => '1',
message => "You didn't supply a parameter.",
do_backtrace => 1);
}
return($ret->return_value);
}
if (demo('foo')){
print "the routine succeeded with one parameter";
}
if (demo()) {
print "The routine succeeded with 0 paramters. shouldn't happen";
} else {
print "The routine failed with 0 parameters (as it should).";
}
my $return = demo();
if ($return) {
print "The routine succeeded with 0 paramters. shouldn't happen";
} else {
print "The routine failed with 0 parameters (as it should). ".
"Stack trace:\n".
$return->backtrace;
}
my @return3 = demo('foo');
print "The routine got ".join(',',@return3).
"when asking for demo's results as an array";
my $return2 = demo('foo');
unless ($return2) {
print "The routine failed with a parameter. shouldn't happen.".
"Stack trace:\n".
$return2->backtrace;
}
my @return2_array = @{$return2}; # TODO: does this work
my @return2_array2 = $return2->as_array;
Instantiate a new Class::ReturnValue object
Return the 'as_array' attribute of this object as an array.
If $self is called in an array context, returns the array specified in ARRAY
Turns this return-value object into an error return object. TAkes three parameters:
message
do_backtrace
errno
'message' is a human readable error message explaining what's going on
'do_backtrace' is a boolean. If it's true, a carp-style backtrace will be
stored in $self->{'backtrace'}. It defaults to true
errno and message default to undef. errno _must_ be specified.
It's a numeric error number. Any true integer value will cause the
object to evaluate to false in a scalar context. At first, this may look a
bit counterintuitive, but it means that you can have error codes and still
allow simple use of your functions in a style like this:
if ($obj->do_something) {
print "Yay! it worked";
} else {
print "Sorry. there's been an error.";
}
as well as more complex use like this:
my $retval = $obj->do_something;
if ($retval) {
print "Yay. we did something\n";
my ($foo, $bar, $baz) = @{$retval};
my $human_readable_return = $retval;
} else {
if ($retval->errno == 20) {
die "Failed with error 20 (Not enough monkeys).";
} else {
die $retval->backtrace; # Die and print out a backtrace
}
}
Returns the errno if there's been an error. Otherwise, return undef
If there's been an error return the error message.
If there's been an error and we asked for a backtrace, return the backtrace. Otherwise, return undef.
If there's been an error, return undef. Otherwise return 1
Jesse Vincent <jesse@bestpractical.com>
This module has, as yet, not been used in production code. I thing
it should work, but have never benchmarked it. I have not yet used
it extensively, though I do plan to in the not-too-distant future.
If you have questions or comments, please write me.
If you need to report a bug, please send mail to
<bug-class-returnvalue@rt.cpan.org> or report your error on the web
at http://rt.cpan.org/
Copyright (c) 2002,2003,2005,2007 Jesse Vincent <jesse@bestpractical.com>
You may use, modify, fold, spindle or mutilate this module under
the same terms as perl itself.
Class::ReturnValue isn't an exception handler. If it doesn't
do what you want, you might want look at one of the exception handlers
below:
Error, Exception, Exceptions, Exceptions::Class
You might also want to look at Contextual::Return, another implementation
of the same concept as this module.
| Class-ReturnValue documentation | Contained in the Class-ReturnValue distribution. |
use warnings; use strict; package Class::ReturnValue;
use Exporter; use vars qw/$VERSION @EXPORT @ISA/; @ISA = qw/Exporter/; @EXPORT = qw /&return_value/; use Carp; use Devel::StackTrace; use Data::Dumper; $VERSION = '0.55'; use overload 'bool' => \&error_condition; use overload '""' => \&error_condition; use overload 'eq' => \&my_eq; use overload '@{}' => \&as_array; use overload 'fallback' => \&as_array;
sub new { my $self = {}; bless($self); return($self); } sub my_eq { my $self = shift; if (wantarray()) { return($self->as_array); } else { return($self); } }
sub as_array { my $self = shift; if (@_) { @{$self->{'as_array'}} = (@_); } return(@{$self->{'as_array'}}); }
sub as_error { my $self = shift; my %args = ( errno => undef, message => undef, do_backtrace => 1, @_); unless($args{'errno'}) { carp "$self -> as_error called without an 'errno' parameter"; return (undef); } $self->{'errno'} = $args{'errno'}; $self->{'error_message'} = $args{'message'}; if ($args{'do_backtrace'}) { # Use carp's internal backtrace methods, rather than duplicating them ourselves my $trace = Devel::StackTrace->new(ignore_package => 'Class::ReturnValue'); $self->{'backtrace'} = $trace->as_string; # like carp } return(1); }
sub errno { my $self = shift; if ($self->{'errno'}) { return ($self->{'errno'}); } else { return(undef); } }
sub error_message { my $self = shift; if ($self->{'error_message'}) { return($self->{'error_message'}); } else { return(undef); } }
sub backtrace { my $self = shift; if ($self->{'backtrace'}) { return($self->{'backtrace'}); } else { return(undef); } }
sub error_condition { my $self = shift; if ($self->{'errno'}) { return (undef); } elsif (wantarray()) { return(@{$self->{'as_array'}}); } else { return(1); } } sub return_value { my $self = shift; if (wantarray) { return ($self->as_array); } else { return ($self); } }
1;