Can't locate object method via package subclassing DBI

这一生的挚爱 提交于 2019-12-13 14:56:23

问题


this is my first foray into subclassing with perl and I am wondering why I am getting this simple error...
"Can't locate object method "prepare" via package "WebDB::st" at /home/dblibs/WebDB.pm line 19.". It seems to find the module WebDB ok, but not the prepare subroutine in ::st
First here's my package (both packages are in one file, WebDB.pm)

package WebDB;
use strict;
use DBI;

sub connect {
    my $dbh = (DBI->connect ("DBI:mysql:test:127.0.0.1", "root","",
                    { PrintError => 1, RaiseError => 0 }));
    return bless $dbh, 'WebDB::st';
}

package WebDB::st;
our @ISA = qw(::st);
sub prepare {
    my ($self, $str, @args) = @_;
    $self->SUPER::prepare("/* userid:$ENV{USER} */ $str", @args);
}


1;

I also tried replacing the "our @ISA = qw(;;st)" with "use base 'WebDB'" and same problem. I'm thinking it's probably something very simple that I'm overlooking. Many thanks! Jane


回答1:


Subclassing DBI has to be done just right to work correctly. Read Subclassing the DBI carefully and properly set RootClass (or explicitly call connect on your root class with @ISA set to DBI). Make sure you have WebDB::st subclassing DBI::st and a WebDB::db class subclassing DBI::db (even if there are no methods being overridden). No need to rebless.

Avoid using base; it has some unfortunate behavior that has led to its deprecation, particularly when used with classes that are not in a file of their own. Either explicitly set @ISA or use the newer parent pragma:

package WebDB;
use parent 'DBI';
...
package WebDB::db;
use parent -norequire => 'DBI::db';
...
package WebDB::st;
use parent -norequire => 'DBI::st';
...



回答2:


Are WebDB and WebDB::st in one file or two? If they are in separate files, I don't see anything that is doing a use WebDB::st;, which would cause that file to be loaded.

You can do either of these things as a remedy -- put the two packages in the same file (that would look exactly as you have pasted it above), or add a use WebDB::st; line in WebDB.pm.

(I'd also add use strict; use warnings; in both these packages too.)

Also, the prepare function is not in ::st -- there is no such package (unless it is defined elsewhere). prepare is in the WebDB::st namespace -- via the package declaration. You are however declaring that WebDB::st has ::st as a parent.




回答3:


If subclassing is as tricky as ysth seems to think, I might recommend Class::Delegator from CPAN. I use if for classes that want to act like IO. And by it, Perl is the first language (that I am aware of) that has an expression language for aggregation, delegation, encapsulation almost equal with inheritance.

package WebDB;
use strict;
use DBI;

use Class::Delegator
    send => [ qw<connect ...> ]
  , to   => '{_dbihandle}'
    ...
  ;


来源:https://stackoverflow.com/questions/4136099/cant-locate-object-method-via-package-subclassing-dbi

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!