2011-11-15 89 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這樣的面向對象的模塊中沒有導入函數,所以爲了簡單起見,我將其忽略了(另外,我沒有在我的例)。 –