2010-08-12 17 views
6

Załóżmy, że mam plik modułu perla i chcę go włączyć i używać dynamicznie w czasie wykonywania. Ten moduł zawiera klasę, której potrzebuję do utworzenia instancji bez znajomości jej nazwy do czasu wykonania.Perl, dynamicznie zawierają pakiet

Na przykład

#inside module.pm 

package module; 

sub new { 
#setup object 
} 

#inside main.pl 

#get module.pm as argument 
my $module_var = #load reference to module using text argument? 
my $module_instance = $module_var->new(); 
+4

Lepszym więcej nowoczesny pomysł tworzyłby klasę bazową i oddzielałby te dynamicznie ładowane byty jako 'MooseX :: Traits', a następnie tworzyliście instancję podstawową ze wspomnianymi cechami' BaseClass-> with_traits ('Foobar :: Baz') -> new; ' –

Odpowiedz

9

Można to zrobić bez eval następująco:

my $module_name = 'Some::Module'; 

(my $require_name = $module_name . ".pm") =~ s{::}{/}g; 

require $require_name; 

my $obj = $module_name->new(); 

Jeśli musisz zrobić to wiele razy, po prostu zawinąć ten kod w podprogramie:

sub load_module { 
    for (@_) { 
     (my $file = "$_.pm") =~ s{::}{/}g; 
     require $file; 
    } 
} 

load_module 'Some::Module', 'Another::Module'; 
+2

["Module :: Load'] (http://p3rl.org/Module::Load) istnieje z tego powodu. – daxim

5
my $module_var = 'module'; 
eval "use $module_var; 1" or die [email protected]; 
my $module_instance = $module_var->new(); 

Należy pamiętać, że jest to możliwe eval dziura bezpieczeństwa. Jeśli $module_var zawiera kod, zostanie wykonany. Jednym ze sposobów obejścia tego jest użycie Class::MOP. Zamienić linię eval z:

use Class::MOP; 
Class::MOP::load_class($module_var); 

Jeśli nie chcesz, aby klasa :: MOP, można skopiować funkcję _is_valid_class_name z niego w kodzie, a tylko upewnić się, że $module_var zawiera poprawną klasę przed wami eval it. (Zauważ, że jeśli używasz Moose, już używasz Class :: MOP za kulisami.)

+0

jest bezpieczniejszy sposób t han eval? bezpieczeństwo jest dla mnie problemem – Mike