Perl Carp

Just really quick, for those perl visitors who have always wondered, what is it exactly that Carp does and why should I be using it?

Let’s assume you have a DB model that handles all db transactions via DBIx::Simple or DBI, etc.

package DB::Model;

use strict;
use warnings;
use Carp qw/croak/;
...
...
sub do {
  my $self = shift;
  my ($schema,$sql,@binds) = @_;
  #$self->logger->("Performing some task... : $sql on $schema");
  $self->db->query($sql,@binds) or croak $self->db->error;
}

Now, in some other part of your program (run.pl)

#!/usr/bin/perl

use strict;
use warnings;

use DB::Model; # or from some IOC or DB provider in your application, etc.

....
$model->do('SELECT id FROM foo INNER JOIN bar USING(id) WHERE id = ? ',$id);

If there’s an error in your SQL statement, the ‘croak’ call will supply the database exception as such :

DBD::mysql::st execute failed: Column 'id' in where clause is ambiguous at lib/DB/Model.pm line xxx

Well, that’s nice, but it’s not very helpful if you have dozens of places in your code where you’re making that call to the database.

If you’re using Carp, you can easily turn on the verbose mode, and watch the stack trace come back to the original caller of the method / function.

#!/usr/bin/perl

use strict;
use warnings;
use Carp;

use DB::Model; # or from some IOC or DB provider in your application, etc.
$Carp::Verbose = 1; #- testing / debugging mode (you can even pass this via command line args)
....
$model->do('SELECT id FROM foo INNER JOIN bar USING(id) WHERE id = ? ',$id);

Which throws the trace :

DBD::mysql::st execute failed: Column 'id' in where clause is ambiguous at lib/DB/Model.pm line xxx
  DB::Model::do('DB::Model','SELECT id FROM foo INNER JOIN bar USING(id) WHERE id = ?',1) called at lib/DB/Model.pm line xxx
  ...
  ...
  Back on up to the original caller

This is really helpful while you’re writing your tests and in active development or are in debug mode.

When you’re done with your testing, you can remove the verbose mode.

Personally, when it’s available, I like to use croak to throw the exceptions in conjunction with a logger class so I can quickly evaluate the full SQL statement + parameters. I have, in times, added additional levels of exception handling by using Class::Exception and Try::Catch blocks around the exceptions for those can may be recovered, or need special warning messages / response codes (think Restful web services and http response codes for various resource exceptions, IE, Invalid Data, etc).

See more information here and here.

  1. No comments yet.

  1. No trackbacks yet.