无法通过包子类化 DBI 定位对象方法
这是我第一次尝试使用 Perl 进行子类化,我想知道为什么我会收到这个简单的错误...
“无法通过包“WebDB::st”在 /home/dblibs/WebDB.pm 第 19 行找到对象方法“prepare”。”。似乎找到了 WebDB 模块,但找不到 ::st
中的准备子例程 首先这是我的包(两个包都在一个文件中,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;
我还尝试将“our @ISA = qw(;;st)”替换为“use base 'WebDB'”和同样的问题。 我想这可能是我忽略的非常简单的事情。非常感谢!简
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
必须正确地对 DBI 进行子类化才能正常工作。仔细阅读对 DBI 进行子类化并正确设置 RootClass (或在根类上显式调用 connect 并将 @ISA 设置为数据库接口)。确保您有 WebDB::st 子类化 DBI::st 和 WebDB::db 类子类化 DBI::db (即使没有方法被重写)。无需再抱怨。
避免使用
base
;它有一些不幸的行为导致它被弃用,特别是当与不在自己的文件中的类一起使用时。显式设置 @ISA 或使用较新的
parent
编译指示: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:WebDB
和WebDB::st
是在一个文件还是两个文件中?如果它们位于单独的文件中,我看不到任何正在执行use WebDB::st;
的操作,这会导致该文件被加载。您可以执行以下任一操作作为补救措施 - 将两个包放在同一个文件中(看起来与上面粘贴的完全相同),或者添加
use WebDB::st;
行在 WebDB.pm 中。(我还会在这两个包中添加
use strict; use warnings;
。)此外,prepare 函数在
::st
不 > -- 没有这样的包(除非它在其他地方定义)。prepare
位于WebDB::st
命名空间中——通过package
声明。但是,您声明WebDB::st
将::st
作为父级。Are
WebDB
andWebDB::st
in one file or two? If they are in separate files, I don't see anything that is doing ause 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 theWebDB::st
namespace -- via thepackage
declaration. You are however declaring thatWebDB::st
has::st
as a parent.如果子类化像 ysth 认为的那样棘手,我可能会推荐
Class::Delegator来自 CPAN 的
。我将 if 用于想要表现得像 IO 的类。由此看来,Perl 是(据我所知)第一种具有与继承几乎相同的聚合、委托、封装表达语言的语言。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 likeIO
. 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.