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

发布于 2024-10-01 13:20:08 字数 694 浏览 5 评论 0原文

这是我第一次尝试使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

茶色山野 2024-10-08 13:20:08

必须正确地对 DBI 进行子类化才能正常工作。仔细阅读对 DBI 进行子类化并正确设置 RootClass (或在根类上显式调用 connect 并将 @ISA 设置为数据库接口)。确保您有 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';
...

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';
...
迷爱 2024-10-08 13:20:08

WebDBWebDB::st 是在一个文件还是两个文件中?如果它们位于单独的文件中,我看不到任何正在执行 use WebDB::st; 的操作,这会导致该文件被加载。

您可以执行以下任一操作作为补救措施 - 将两个包放在同一个文件中(看起来与上面粘贴的完全相同),或者添加 use WebDB::st; 行在 WebDB.pm 中。

(我还会在这两个包中添加 use strict; use warnings;。)

此外,prepare 函数在 ::st不 > -- 没有这样的包(除非它在其他地方定义)。 prepare 位于 WebDB::st 命名空间中——通过 package 声明。但是,您声明 WebDB::st::st 作为父级。

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.

浅听莫相离 2024-10-08 13:20:08

如果子类化像 ysth 认为的那样棘手,我可能会推荐 Class::Delegator来自 CPAN 的。我将 if 用于想要表现得像 IO 的类。由此看来,Perl 是(据我所知)第一种具有与继承几乎相同的聚合、委托、封装表达语言的语言。

package WebDB;
use strict;
use DBI;

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

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}'
    ...
  ;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文