Как вы динамически включаете модуль, основываясь на том, какие модули доступны? - PullRequest
2 голосов
/ 15 ноября 2011

У меня есть Perl-скрипт, который использует CGI :: Session :: Drive :: memcached, но я хочу иметь возможность откатить драйвер Session по умолчанию или другой драйвер, если он доступен в системе ...

Вот как я начал использовать Memcache, но это не обязательно решает проблему в случае, когда Cache :: Memecached и / или CGI :: Session :: Driver :: memcached недоступны ...

package MySession;

use Moose::Role;
use Moose::Util::TypeConstraints; 
use namespace::autoclean;

use CGI::Session ('-ip_match');
use CGI::Session::Driver::memcached;
use Cache::Memcached::Fast;

#would be nice to create this conditionally, or use a delegate maybe
has 'memeCached' => (
 is        => 'rw', 
 isa       => 'Maybe[Cache::Memcached::Fast]', 
 default => sub{ return Cache::Memcached::Fast->new( {'servers' => [ '10.x.x.x.:10001' ],'compress_threshold' => '100000','nowait' => 1,'utf8' => 1} ) },

);


  sub buildSession{
    my($this,$cgi,$sessionDir) = @_;

    $cgi = $cgi || $this->getCGI();

    my $sid = $this->SID();        
    my $mem = $this->memeCached(); 

    my $sss;

    if(!$mem){
        $sss = CGI::Session->load(undef, $cgi, {Directory=>$sessionDir}) or die CGI::Session->errstr();
    }else{
            $sss = CGI::Session->load( "driver:memcached", $cgi, { Memcached => $mem }) or die CGI::Session->errstr();
    }

...

Тогда это заставило меня задуматься, как мне это сделать - в общем смысле? или каков наилучший способ сделать это (особенно с помощью Moose)?

1 Ответ

3 голосов
/ 15 ноября 2011

У меня была похожая ситуация.Мы используем домены Windows, которые я могу подключить к Net :: LDAP.В моей программе я хочу иметь возможность использовать идентификатор пользователя jsmith, и вместо того, чтобы печатать его, я хочу распечатать имя John Smith.

Многие люди вмоя компания использует мою программу, но не все являются экспертами по Perl, и большинство из них не знают, как установить модуль Perl.И, поскольку Net :: LDAP не является стандартным модулем, у многих людей его нет.

Вместо этого я хотел использовать резервную процедуру.Если бы я мог найти имя с помощью Net::LDAP, я бы напечатал имя, если я не смог загрузить Net::LDAP, я бы отступил и просто напечатал идентификатор пользователя.

Я использовал следующее для тестированияесли был установлен Net::LDAP, и, если возможно, загрузите его:

BEGIN {
    eval { require Net::LDAP; };
    our $Net_Ldap_Status  = 1 if (not $@);
}

Вы должны понять, что:

use Foo::Bar;

- это то же самое, что и

BEGIN {
    require Foo::Bar;
}

Загружается в модуль в время компиляции .Окружив require eval, я могу проверить, успешно ли выполняется оператор (и загружен ли модуль) или нет (модуль не загружается, но программа также не падает.) Затем я могу проверить $@, чтобы увидеть, загружен модуль или нет.$@ - это сообщение об ошибке, которое устанавливает eval.Если $@ равно нулю, то модуль существует и был успешно загружен.

Мне нужно использовать переменную пакета (our $Net_Ldap_Status вместо my $Net_Ldap_Status), иначе переменная будет потеряна при запуске программы,(Я даже не уверен, что my $Net_Ldap_Status сработает в операторе BEGIN).

Теперь вот где все становится смешно ...

Когда мне нужно проверить $Net_Ldap_Status, Мне нужно переопределить его:

our $Net_Ldap_Status;

или я получаю эту необъявленную переменную ошибку.Самое смешное, что он не теряет своего прежнего значения, если его заново обозначить.Таким образом, где-то в моем коде есть:

our $Net_Ldap_Status;
if ($Net_Ldap_Status) {
   print "Code if Net::LDAP is loaded.\n";
}
else {
   print "Fallback Code if no Net::LDAP\n";
}
...