Не удается найти метод объекта с помощью DBI, создающего подклассы - PullRequest
3 голосов
/ 09 ноября 2010

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

Ответы [ 3 ]

10 голосов
/ 09 ноября 2010

Создание подклассов 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';
...
0 голосов
/ 10 ноября 2010

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

package WebDB;
use strict;
use DBI;

use Class::Delegator
    send => [ qw<connect ...> ]
  , to   => '{_dbihandle}'
    ...
  ;
0 голосов
/ 09 ноября 2010

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

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

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

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

...