无法通过包子类DBI定位对象方法

时间:2010-11-09 16:36:06

标签: perl oop subclass dbi

这是我第一次尝试使用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)”和同样的问题。 我认为这可能是我非常简单的事情。非常感谢!简

3 个答案:

答案 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)

WebDBWebDB::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}'
    ...
  ;