如何基于可用的模块动态包含模块?

时间:2011-11-15 02:06:42

标签: perl module include require moose

我有一个使用CGI :: Session :: Drive :: memcached的perl脚本,但我希望能够在默认的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 个答案:

答案 0 :(得分:3)

我有类似的情况。我们使用Windows域,我可以连接到Net :: LDAP。在我的程序中,我希望能够获取用户ID jsmith,而不是打印用户ID,我希望能够打印出名称John Smith

我公司的很多人都使用我的程序,但并非所有人都是Perl专家,大多数人都不知道如何安装Perl模块。而且,由于Net :: LDAP不是标准模块,很多人都没有。

相反,我想要一个后备程序。如果我可以使用Net::LDAP查找名称,我会打印名称,如果我无法加载Net::LDAP,我会回退并只打印用户ID。

如果安装了Net::LDAP,我使用以下内容进行测试,并在可能的情况下加载它:

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

您必须了解的是:

use Foo::Bar;

与:

相同
BEGIN {
    require Foo::Bar;
}

它在 compile 时加载到模块中。通过用require包围eval,我可以测试语句是否成功(并且模块已加载)或失败(模块未加载,但程序也不会崩溃。)I然后可以检查$@以查看是否加载了模块。 $@是eval设置的错误消息。如果$@为null,则模块存在并成功加载。

我需要使用包变量(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";
}
相关问题