I have written a number of modules that make use of storing an error string to be called by the caller for retrieval. I am running my code through Perl::Critic and I think I need to refactor this idea to make it more "The Right Way(tm)." Below is some pseudo code with some sample methods.
package Object;
sub new {
my $class = shift;
my $self = { 'ERRSTR' => undef };
bless $self, $class;
return $self;
}
sub _errstr {
return $_[0]->{'ERRSTR'};
}
sub _login {
my $self = shift;
eval {
...
$self->{'CONNECTION'} = ....
};
if($@) {
$self->{'ERRSTR'} = $@;
return 1;
}
return 1;
}
sub _ping {
my $self = shift;
eval {
if(not $self->{'CONNECTION'}) {
$self->login() or die $self->errstr();
}
....
};
if($@) {
$Self->{'ERRSTR'} = $@;
return 0;
}
return 1;
}
# This allows me to control nesting so that debug statements are inden
+ted by 1 space so that
# I can easily see the flow if I call Object->set_debug(1) from the ap
+plication.
AUTOLOAD {
our $AUTOLOAD;
my $request = undef;
my $funcs = {
'ping' => sub { _ping(@_); },
..
};
if($AUTOLOAD =~ m/^Object::(.+?)$/) {
$request = $1;
foreach my $ref (keys %{ $funcs }) {
next unless $ref eq $request;
... increment debug indention ...
my $val = $funcs->{$ref}->($@);
... decrement debug indention ....
return $val;
}
}
die "Method ${AUTOLOAD} does not exist."
}
Many methods call other object methods as needed. This particular module
use SOAP::Lite to connect to a web server. I've abstracted all SOAP code from
the application and reduced it to something like this:
use Object.
sub main {
eval {
my $service = Object->new("127.0.0.1", .....);
$service->ping() or die $service->errstr();
};
if($@) {
warn "$@";
return 1;
}
return 0;
}
exit main;
Every time I want the application to be as few lines as possible and simple I'll write a module that will
abstract the real module and do maintenance tasks. I do this most often with DBI where I'll target a SQLite file.
The application will call methods that will manipulate data in the database. The module will check the integrity of the db, create it if it does not exist, vacuum if needed, etc.
I use the same module with
$self->{'ERRSTR'}
As I convert the
die() to
croak() in Object I'm concerned that my method of writing the object is not compatible with Carp's stacktrace.