Xpoint
   [напомнить пароль]

Динамический вызов модуля

Метки: [без меток]
[удл]
2010-03-09 07:53:50 [обр] AB...(12/227)[досье]

Проблема состоит в том, что надо вызывать модуль iw.pm, и передавать параметер для динамического подключения иного (пример test.pm, но этим не ограничивается). Все это для того, чтобы для каждый template создавать модуль который на выходе будет иметь несколько одноименных методов.

Вызов происходит с test.pl
Знаю, что данная проблема решаетсяю. Читал несколько лет назад, но никогда не использовал и к сожалению не помню где это было. Если бы вспомнить правльный термин к данному методу, то можно было бы найти пример.

Приведенный код не работает - выдает Can't locate template::test in @INC
Буду признателен за любую полезный совет.

iw.pm

package template::iw;
use strict;
use warnings;

sub new {
    my $that  = shift;
    my $class = ref(shift) || $that;
    my $self  = { 
        "o" => undef
    };
    bless $self, $class;
    return $self;
}

sub init {
    my ($self, $inp) = @_;
    if (defined $inp) {
        my $temp = qw(template::).$inp;
        require $temp;
        $self->{"o"} = $temp->new();
    }
    return $self->{"o"};
}
1;

test.pm

package template::test;
use strict;
use warnings;

sub new {
    my $class = shift;
    my $self = {
                "x"  => undef
                };
    bless ($self, $class);
    return $self;
}

sub x {
    my ($self, $inp) = @_;
    $self->{"x"} = $inp if defined ($inp);
    return $self->{"x"};
}
1;

test.pl

use template::iw;
my $iw = template::iw->new();
my $test = $iw->init(qw~test~);
print $test->x("alex");
спустя 5 минут [обр] AB...(12/227)[досье]
Допустил ошибку в test.pl, правильный код ниже. Тем ни менее это дело не исправило, так как дело в самом методе.
use template::iw;
my $iw = template::iw->new();
my $test = $iw->init(qw~test~);
print $iw->x("alex");
спустя 1 час 47 минут [обр] Алексей Севрюков(56/1056)[досье]
Я все таки уточню, а путь к template::test прописан в @INC?
спустя 1 час 21 минуту [обр] Евгений Седов aka KPbIC(0/17)[досье]
AB...[досье] Я бы на вашем месте либо генерировал класс в template::iw, либо подгрузил всех хелпер-классы и возвращал экземпляр одного из них по запросу.
спустя 6 часов [обр] AB...(12/227)[досье]
Алексей Севрюков[досье] определено могу сказать, что модули в правильном месте perl/site/lib/. когда я на рямую подключаю мадуль use tepmale::test все работает нормально, а динамичси ругаетя.
спустя 2 минуты [обр] AB...(12/227)[досье]
Евгений Седов aka KPbIC[досье] фокус в том и состаит, чтобы модули были отдеьно. они будут увеличиваться в количестве базируясь на объеме templates
спустя 2 часа 3 минуты [обр] Евгений Седов aka KPbIC(0/17)[досье]

AB...[досье]

модули в правильном месте

Алексей Севрюков[досье] задал вам другой вопрос:

путь к template::test прописан в @INC
спустя 54 минуты [обр] Алексей Севрюков(56/1056)[досье]

perldoc require

The require function will actually look for the ``Foo/Bar.pm'' file in the directories specified in the @INC array.

    But if you try this:

            $class = 'Foo::Bar';
            require $class; # $class is not a bareword
        #or
            require "Foo::Bar"; # not a bareword because of the ""

    The require function will look for the ``Foo::Bar'' file in the @INC array and will complain about not finding ``Foo::Bar'' there. In this case you can do:

            eval "require $class";

То, что Вы делаете, я делаю с помощью perldoc do. Вы можете использовать require, но тогда Вам нужно указывать имя файла, а не название модуля. Про eval говорить не буду, Вы и сами знаете.
Да, согласен, ошибка не информативная Can't locate template::test in @INC, но если присмотреться, то

use template::notexist;

 выдает уже Can't locate template/notexists.pm in @INC.
Разница очевидна.

спустя 7 минут [обр] Алексей Севрюков(56/1056)[досье]

Евгений Седов aka KPbIC[досье], AB...[досье] ответил на мой конкретный вопрос полностью:

когда я напрямую подключаю модуль use tepmale::test, все работает нормально

этого достаточно чтобы понять что пути прописаны верно.

спустя 7 часов [обр] AB...(12/227)[досье]

Пробую Reflection процесс с небольшой модификацией, так как по умолчанию reflection процесс предпологает только один модуль со вложенными packages, так вот это тоже не работает.
iw.pm

package template::iw;
use strict;
use warnings;

sub new {
    my $that  = shift;
    my $class = ref($that) || shift;
    my $self  = {
        "o" => undef
    };
    bless $self, $class;
    return $self;
}

sub foo {
    my ($self,$inp) = @_;
    print "working : iw";
}
1;

test.pm

package template::test;
use strict;
use warnings;
use base qw/template::iw/;
#use template::iw;

sub foo {
    my ($self,$inp) = @_;
    print "working : test";
    $self->SUPER::foo();
}
1;

test.pl

use strict;
use template::iw;
my $class = 'template::test';
my $iw = template::iw->new($class);
eval { $iw->foo(); };
print "error :".$@."\n";

К примеру, $iw получает type template::test после инициализации и после этого я получаю ошибку от $iw->foo метода:

Can't locate object method "foo" via package "template::test"

Получается так, что уже недоступны методы как с template::iw, так и с template::test классов.

спустя 2 часа 7 минут [обр] AB...(12/227)[досье]

Проблема решена!
Использую Polymorphism и для решения проблемы @INC применяю eval.
Приведу код, может кому понадобиться для решения подобной задачи.
iw.pm

package template::iw;
use strict;
use warnings;
use Carp qw(croak);

sub new {
    my $class = shift;
    croak "Bad class parameter" if (not defined $class or ref($class));
    my $other = shift;
    my $self  = {};
    if ($other) {
        $other = "template::".$other;
        eval "use $other;";
        croak "Cannot find class : error:".$@ if $@;
        $self = $other->new();
        bless $self, $other;
    } else {
        bless $self, $class;
    }
    return $self;
}
1;

test.pm

package template::test;
use strict;
use warnings;
use base qw/template::iw/;

sub new {
    my $class = shift;
    my $self = bless {}, $class;
    return $self;
}

sub foo {
    my ($self,$inp) = @_;
    $inp = "" unless defined $inp;
    return "test : ".$inp;
} 
1;

test.pl

use strict;
use template::iw;
my $class = "test";
my $iw = template::iw->new($class);
print $iw->foo("okay");

Спасибо всем за участие.

Твой WebClub!
Powered by POEM™ Engine Copyright © 2002-2005