Why would the rollback method not be available for a DBI handle?
Question
For some reason I am having troubles with a DBI handle. Basically what happened was that I made a special connect function in a perl module and switched from doing:
do 'foo.pl'
to
use Foo;
and then I do
$dbh = Foo->connect;
And now for some reason I keep getting the error:
Can't locate object method "rollback" via package "Foo" at ../Foo.pm line 171.
So the weird thing is that $dbh is definitely not a Foo, it's just defined in foo. Anyway, I haven't had any troubles with it up until now. Any ideas what's up?
Edit: @Axeman: connect
did not exist in the original. Before we just had a string that we used like this:
do 'foo.pl';
$dbh = DBI->connect($DBConnectString);
and so connect
is something like this
sub connect {
my $dbh = DBI->connect('blah');
return $dbh;
}
Solution
From perlfunc:
do 'stat.pl'; is just like eval `cat stat.pl`;
So when you do 'foo.pl'
, you execute the code in the current context. Because I don't know what goes on in foo.pl
or Foo.pm
, I can't tell you what's changed. But, I can tell you that it's always executed in the current context, and now in executes in Foo::
namespace.
The way you're calling this, you are passing 'Foo'
as the first parameter to Foo::connect
or the returned sub from Foo->can('connect')
. It seems that somehow that's being passed to some code that thinks it's a database handle, and that's telling that object to rollback
.
OTHER TIPS
We need to see the actual code in Foo to be able to answer this. You probably want to read Subclassing the DBI from the documentation to see how to do this properly.
Basically, you either need Foo to subclass DBI properly (again, you'll need to read the docs), or you need to declare a connect function to properly delegate to the DBI::connect method. Be careful about writing a producedural wrapper for OO code, though. It gets awfully hard to maintain state that way.
I agree with Axeman. You should probably be calling your function using
use Foo;
...
$dbh = Foo::connect();
instead of Foo->connect();