Невозможно найти метод объекта с помощью DBI-подкласса пакета

это мой первый набег на создание подклассов с помощью perl, и мне интересно, почему я получаю эту простую ошибку ...
«Не могу найти метод объекта» prepare »с помощью пакета« WebDB :: st »в / home / dblibs /WebDB.pm, строка 19. ". Кажется, что модуль 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;

Я также попытался заменить «наш @ISA = qw (;; st)» на «использовать базу 'WebDB'» и та же проблема. Я думаю, что это, вероятно, что-то очень простое, на что я не обращаю внимания. Большое спасибо! Джейн


person Jane Wilkie    schedule 09.11.2010    source источник


Ответы (3)


Создание подклассов DBI должно выполняться правильно, чтобы работать правильно. Внимательно прочтите Создание подкласса 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';
...
person ysth    schedule 09.11.2010
comment
ysth! Ты жжешь! Это отлично сработало! Я редактирую код другого человека (который, к сожалению, покинул нашу компанию), и я. счастлив за этот ответ и б. счастлив более подробно изучить подклассы. - person Jane Wilkie; 09.11.2010

WebDB и WebDB::st в одном или двух файлах? Если они находятся в разных файлах, я не вижу ничего, что делает use WebDB::st;, что могло бы вызвать загрузку этого файла.

Вы можете сделать одно из этих действий в качестве средства правовой защиты - поместить два пакета в один и тот же файл (который будет выглядеть точно так, как вы вставили его выше) или добавить строку use WebDB::st; в WebDB.pm.

(Я бы также добавил use strict; use warnings; в оба этих пакета.)

Кроме того, функция подготовки отсутствует в ::st - такого пакета нет (если он не определен где-либо еще). prepare находится в пространстве имен WebDB::st - через объявление package. Однако вы заявляете, что WebDB::st имеет ::st в качестве родителя.

person Ether    schedule 09.11.2010
comment
Спасибо, Эфир. Они находятся в одном файле. Я отредактирую это в. JW - person Jane Wilkie; 09.11.2010

Если создание подклассов настолько сложно, как кажется ysth, я могу порекомендовать Class::Delegator из CPAN . Я использую if для классов, которые хотят действовать как IO. Таким образом, Perl является первым языком (о котором я знаю), который имеет язык выражений для агрегирования, делегирования и инкапсуляции, почти равный наследованию.

package WebDB;
use strict;
use DBI;

use Class::Delegator
    send => [ qw<connect ...> ]
  , to   => '{_dbihandle}'
    ...
  ;
person Axeman    schedule 09.11.2010
comment
это сложно только потому, что DBI пытается сделать часть работы за вас, и в ней задействовано несколько классов. - person ysth; 21.02.2013