2011-11-15 63 views
2

我有一个使用CGI :: Session :: Drive :: memcached的perl脚本,但是我希望能够在默认会话驱动程序或其他驱动程序上备份,如果它在系统上可用的话...如何根据可用模块动态地包含模块?

这是我开始时使用内存缓存,但这并不一定能解决的情况下的问题,当缓存:: Memecached和/或CGI ::会议::驱动程序:: 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)?

回答

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 [email protected]); 
} 

你要明白那是什么:

use Foo::Bar; 

是一样的:

BEGIN { 
    require Foo::Bar; 
} 

它加载到模块中编译时间。通过围绕requireeval我可以测试语句是否成功(和模块加载)或失败(模块不加载,但程序不会崩溃)。然后我可以检查[email protected],看看是否模块加载或没有。 [email protected]是eval设置的错误消息。如果[email protected]为空,则该模块存在并已成功加载。

我需要使用包变量(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"; 
} 
+0

'use Foo :: Bar;'实际上更接近'BEGIN {require Foo :: Bar; import Foo :: Bar; }'。但是,由于通常情况下导入没有用处,因此不调用'import'可能是一个好主意。 – ikegami

+0

你使用mod_perl吗?这也许可以解释为什么重新宣布我们没有核武器的价值。 +1的轶事例如 – qodeninja

+1

@ikegami的确,如果你的Perldoc看[使用](http://perldoc.perl.org/functions/use.html),它包括进口。但是,在Net :: LDAP和CGI :: Session :: Driver :: memcached这样的面向对象的模块中没有导入函数,所以为了简单起见,我将其忽略了(另外,我没有在我的例)。 –