($module) = ($module =~ /^([[\w:']]+)$/);
2017-09-06T14:25:14 Max_PerlbeginnerDa ich also zu Beginn noch gar nicht weiß, welche Plugins verwendet oder gar installiert werden, muss ich diese dynamisch bei Bedarf nachladen.
1 2 3 4 5 6 7 8
my $mname = 'Win32::DriveInfo'; my $modul = 1; eval "use $mname; 1;" or $modul = 0; if ($modul) { say "... Modul ist geladen ..."; say join '*',Win32::DriveInfo::DriveSpace('c'); } else { say "... Modul fehlt ..." }
2017-09-06T19:35:54 Max_Perlbeginnerohne zu verstehen, dass eval "string" etwas Anderes ist als eval {block}.
2017-09-07T07:20:59 Max_Perlbeginnereval "require $module" ist dafür erforderlich, dass Perl $module als Bareword behandelt. Wenn ich nur require $module schreiben würde, wäre das nicht der Fall, weswegen sich require anders als erwartet verhalen würde. Details, siehe hier
2017-09-07T07:37:52 rostiDas kann Max_Perlbeginner ja nicht wissen ;-) Außerdem sind solche Links vielleicht für andere hilfreich2017-09-07T07:20:59 Max_Perlbeginnereval "require $module" ist dafür erforderlich, dass Perl $module als Bareword behandelt. Wenn ich nur require $module schreiben würde, wäre das nicht der Fall, weswegen sich require anders als erwartet verhalen würde. Details, siehe hier
Du musst mich nicht auf die Dokumentation verweisen, die kenne ich.
2017-09-07T07:37:52 rostiIhr habt ja beide recht. Einfach require $module würde nicht reichen. Also entweder ein String-eval oder vorher in einen Pfad umwandeln... (wobei ich auch eher erst die Umwandlung in einen Pfad machen würde)Gerade require braucht ja kein Bareword, da kannst Du auch Variablen einsetzen und das Tolle daran ist, require guckt selbst in @INC. Du musst allenfalls den :: durch / ersetzen und dann geht das auch ohne Umschweife direkt:
MfG
2017-09-07T06:23:49 rostieval "use xy" ermöglich also lediglich ein nach dem BEGIN{} Block späteres Nachladen vom Code der mit use eingebunden werden soll. Was mit require aber auch ohne eval möglich ist.
2017-09-08T09:36:22 reneeSTRING-evals würde ich vermeiden wo es geht.
2017-09-08T09:36:22 reneeVor allem wenn Inhalte "von außen" kommen und man somit nicht die volle Kontrolle über das hat was beim eval ausgeführt wird.
Stell dir vor, in $mname steht so etwas wie "CGI; system('rm -rf /');" ...
2017-09-11T04:27:21 reneeDeswegen schrieb ich "von außen". Es gibt genügend Webapps, die so etwas wie "action=einkauf" in den Parametern erlauben und dann einfach machen...
1 2 3 4
require "factory/param.pm"; my $m = bless{}; $m->param(); print Dumper $m;
1 2 3 4 5 6 7 8 9 10 11 12 13
$VAR1 = bless( { 'CGI' => bless( { 'CONTENT_LENGTH' => 0, 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 'CONTENT_TYPE_ORIGIN' => 'application/x-www-form-urlencoded', 'QUERY_STRING' => '', 'STDIN' => bless( \*Symbol::GEN0, 'IO::String' ), 'eav' => {}, 'json' => {}, 'param' => {}, 'rawdata' => '' }, 'xCGI' ) }, 'main' );
1 2 3 4 5 6 7 8 9 10 11 12
package UNIVERSAL; use xCGI; sub param{ my $self = shift; $self->{CGI} = xCGI->new() unless defined $self->{CGI}; return $self->{CGI}->param(@_); } 1;
2017-09-07T07:33:35 MuffiWenn einfach alles geladen wird, kann das auch unangenehme Folgen haben. In der Regel wird das ja dann alphabetisch sortiert geladen. Da kann ich was überschreiben was ich eigentlich behalten will.Dann machs doch einfach so wie der Rest der Welt. Das muss in ein Plugins-Verzeichnis und alles was da drin liegt wird geladen.
QuoteIch mache es z.B. so, dass man in vielen Fällen in einer Konfigdatei sagen kann, welche Backends geladen werden sollen
QuoteÜber Pluginmechanismen und deren Vor- und Nachteile kann man glaube ich tagelang diskutieren.
QuoteKannst Du mal ein komplettes Beispielprogramm posten? Denn auch Subklassen müssen irgendwie geladen werden...
1
2
3
4
my $class = $routes->{$url}{class} || 'NotFound';
my $classfile = $class;
$classfile =~ s|::|/|g;
require "$classfile.pm";
QuoteErster Schritt: Klassenbindung. Wozu haben wir denn OOP!? Machen wir Plugins zu Subklassen und schon ist das Problem mit dem Nachladen gelöst, ganz ohne die hier vorgestellten Helper-Module.
2017-09-11T07:24:31 reneeDann passt aber Deine Aussage nichtQuoteErster Schritt: Klassenbindung. Wozu haben wir denn OOP!? Machen wir Plugins zu Subklassen und schon ist das Problem mit dem Nachladen gelöst, ganz ohne die hier vorgestellten Helper-Module.
Nur durch das Erstellen wird kein Problem gelöst. Du musst trotzdem ein require machen und das ist unabhängig davon, ob das ein Skript, ein "normales" Modul oder eine (Sub-)Klasse ist.