这是我第一次尝试使用perl进行子类化,我想知道为什么我会遇到这个简单的错误...
“无法在/home/dblibs/WebDB.pm第19行通过软件包”WebDB :: st“找到对象方法”prepare“。”它似乎找到了模块WebDB ok,但没有找到:: st
中的prepare子例程
首先是我的包(两个包都在一个文件中,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;
我也尝试用“use base'WebDB'”替换“我们的@ISA = qw(;; st)”和同样的问题。 我认为这可能是我非常简单的事情。非常感谢!简
答案 0 :(得分:10)
必须正确完成子类化DBI才能正常工作。仔细阅读Subclassing the DBI并正确设置RootClass(或者在根类上显式调用connect,并将@ISA设置为DBI)。确保你有WebDB :: st子类化DBI :: st和一个WebDB :: db类子类化DBI :: db(即使没有被覆盖的方法)。无需重新考虑。
避免使用base
;它有一些不幸的行为导致它被弃用,特别是当与不属于自己的文件的类一起使用时。
显式设置@ISA或使用较新的parent
编译指示:
package WebDB;
use parent 'DBI';
...
package WebDB::db;
use parent -norequire => 'DBI::db';
...
package WebDB::st;
use parent -norequire => 'DBI::st';
...
答案 1 :(得分:0)
WebDB
和WebDB::st
是一个还是两个文件?如果它们位于单独的文件中,我看不到任何正在执行use WebDB::st;
的操作,这会导致加载该文件。
您可以将这些内容中的任何一个作为补救措施 - 将两个包放在同一个文件中(看起来与您上面粘贴的完全相同),或者在WebDB.pm中添加use WebDB::st;
行。
(我也会在这两个包中添加use strict; use warnings;
。)
此外,准备功能在::st
中不 - 没有这样的包(除非在别处定义)。 prepare
位于WebDB::st
命名空间中 - 通过package
声明。但是,您声明WebDB::st
已将::st
作为父母。
答案 2 :(得分:0)
如果子类化和ysth似乎一样棘手,我可能会推荐CPAN中的Class::Delegator
。对于想要像IO
那样行事的类,我使用if。通过它,Perl是第一种语言(我所知道的),它具有聚合,委托,封装的表达式语言,几乎与继承相同。
package WebDB;
use strict;
use DBI;
use Class::Delegator
send => [ qw<connect ...> ]
, to => '{_dbihandle}'
...
;