package TestModule; require DBI; use AutoLoader; use base 'Class::Base'; sub AUTOLOAD { my $op = $AUTOLOAD; $op =~ s/^.*:://; if ( DBI::db->can($op) ) { eval "sub $op { my \$self=shift; $self->{DBH}->$op(\@_); }"; } else { eval "sub $op { return shift->error('Cannot autoload $op'); }"; } } sub new { # new ( $dsn[, $user[, $pass]] ) my $self = shift; return undef unless @_; my @args = @_; my $obj = {}; eval { $obj->{DBH} = DBI->connect(@args); }; if ($@) { return $self->error("Unable to connect to DB: $@"); } bless $obj, $self; } #### use Test::More tests => 9; # ... snipped setup of $obj = new & etc. my $sth = $obj->prepare('SELECT * FROM test_table'); can_ok($obj, 'prepare'); #succeeds! # this fails: isnt ($sth, undef, 'prepare creates statement handle'); #### sub AUTOLOAD { my $op = $AUTOLOAD; $op =~ s/^.*:://; if ( DBI::db->can($op) ) { eval "sub $op { return shift->{DBH}->$op(\@_); }"; $op->(@_); } else { eval "sub $op { return shift->error('Cannot autoload $op'); }"; } } #### # sets up autoload subs that 'inherit' DBI's DBH methods sub AUTOLOAD { my $op = $AUTOLOAD; my $self = shift; $op =~ s/^.*:://; if ( DBI::db->can($op) ) { # create a wrapper for a DBH method eval "sub $op { return shift->{DBH}->$op(\@_); }"; $op->($self, @_); } elsif ( $op =~ /^_/ ) { # return the appropriate attribute $op =~ s/^_//; exists $self->{$op} && return $self->{$op}; return $self->error("Can't autoload for attribute _$op"); } else { return $self->error("Cannot autoload $op"); } }