views:

263

answers:

3

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;
}
+4  A: 

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.

Axeman
Yeah, that was the error. I wanted a static method and I was pretending Foo was a class, and it's not, it's a package. Thanks!
Frew
+3  A: 

I agree with Axeman. You should probably be calling your function using

use Foo;
...
$dbh = Foo::connect();

instead of Foo->connect();

Frentos
+7  A: 

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.

Ovid