2010-11-09 5 views
3

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

ответ

8

Подклассификация DBI должна выполняться правильно, чтобы работать правильно. Прочитайте Subclassing the DBI тщательно и правильно установите RootClass (или явно вызовите соединение в своем корневом классе с @ISA, установленным в DBI). Удостоверьтесь, что у вас есть подклассы WebDB :: st DBI :: st и класс subclassing класса DBD :: db класса WebDB :: 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

ysth! Ты жжешь! Это здорово! Я редактирую некоторые другие коды (которые, к сожалению, покинули нашу компанию), и я a. счастлив за этот ответ и б. с удовольствием копаем больше в подклассификацию. –

0

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

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

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

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

+0

Thanks Ether. Они находятся в одном файле. Я отредактирую это. JW –

0

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

package WebDB; 
use strict; 
use DBI; 

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

это только сложно, потому что DBI пытается выполнить часть работы для вас и нескольких классов. – ysth

Смежные вопросы