Schrift
[thread]679[/thread]

Dynamische Includes in perl



<< |< 1 2 >| >> 12 Einträge, 2 Seiten
Gast Gast
 2006-02-23 16:14
#7010 #7010
Hi

ich arbeite grade an einem CGI-Perl-System. Es soll eine index.pl geben die einen Verzeichnisbaum durchsucht. In jedem Verzeichnis können mehrere .pl-Dateien liegen aus denen jeweils eine Funktion (getName) aufgerufen werden soll. Wie macht man sowas in Perl?
Strat
 2006-02-23 17:16
#7011 #7011
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
rekursives durchsuchen eines Verzeichnisbaums: CPAN:File::Find oder CPAN:File::Find::Rule

Perl-Modul (bzw. Perl-Datei) laden, von der man nur Pfad und Namen kennt:
gib mal perldoc -f require in deine shell ein
Dabei wird aber beim Laden der Code, der nicht in Subroutinen steht, ausgefuehrt.
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
mood42
 2006-02-24 11:54
#7012 #7012
User since
2006-02-24
4 Artikel
BenutzerIn
[default_avatar]
Hi

das hat mal soweit geklappt das ich eine Datei einbinden kann. Bei mehreren kommt es natürlich zu Namensüberschneidungen. Die hab ich jetzt versucht mit packages zu lösen. Allerdings kann ich dann nicht mehr so ohne weiteres auf die Subroutinen innerhalb der Dateien zugreifen da ich den Namen des Package garnicht kenne. Ich hab dann versucht die Symboltabelle des Package zurückzugeben aber auch das hat nicht geklappt. Kann mir da jemand helfen?
dominicn
 2006-02-24 12:20
#7013 #7013
User since
2003-08-08
327 Artikel
BenutzerIn
[default_avatar]
Du könntest ja in der datei außerhalb der Subroutinen einen Befehl schreiben, der z.B. eine Referenz auf die Subroutinge getName() in einen Array schiebt. Also z.B. sowas:

Code: (dl )
push(@subroutines, \&getName)


Ich denke, das müsste so funktionieren, ganz sauber ist es evtl. nicht. Vorher solltest du möglichst die Liste @subroutines im Hauptscript anlegen.
renee
 2006-02-24 13:52
#7014 #7014
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Kannst Du vielleicht etwas abstrahieren, was Du eigentlich genau erreichen willst?? Mir erschliesst sich das Ganze noch nicht so ganz...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
mood42
 2006-02-24 14:44
#7015 #7015
User since
2006-02-24
4 Artikel
BenutzerIn
[default_avatar]
ich möchte eine Reihe von Scripten in ein Verzeichnis legen die alle die gleiche Schnittstelle aufweisen (getName, doSomething usw.)

Jedes dieser Module soll dann von einem Hauptscript aus aufgerufen werden können. Die Installation eines solchen "Moduls" soll dann einfach durch kopieren in das passende Verzeichnis geschehen.

Also im Prinzip nichts anderes als ein Plugin-System wie man es von zig Applikationen kennt. DLL oder SO in ein Verzeichnis kippen und die Applikation ruft dann auf allen DDLs einen gegebenen Satz von Funktionen auf. Und das eben in Perl.
renee
 2006-02-24 14:49
#7016 #7016
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Wie Strat schon gesagt hat, erstmal die Dateinamen mit CPAN:File::Find holen und dann mit require (siehe perldoc -f require) einbinden. Du musst Dir ja ein System fuer die Namensgebung ueberlegt haben und wie Du eine Funktion aufrufen willst...

z.B. so Verzeichnis /plugin

Mail.pm


im Code dann
Code: (dl )
1
2
3
4
5
6
7
8
# mit File::Find die .pm-Dateinamen auslesen und in @modules speichern

foreach my $module(@modules){
require $module;
}

my $wanted = 'Mail'; #Name des Moduls, das genutzt werden soll
&{$wanted}->(@parameter);


Das nur als ganz grobe Skizzierung...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
mood42
 2006-02-24 15:04
#7017 #7017
User since
2006-02-24
4 Artikel
BenutzerIn
[default_avatar]
Hi

ich sehe, wir kommen der Sache näher. Die Namen der Module (packages) habe ich und sie sind auch per require geladen. Jetzt muss ich eben mit dem Namen dieses package (der als String vorliegt) irgendwas aus diesem package aufrufen können. Und das ist mir nicht ganz klar wie ich das machen soll.

Kleines Beispiel:

plugin1:
Code: (dl )
1
2
3
4
5
6
7
8
package foo;

sub getName
{
return "Foo plugin";
}

'foo';


Den Dateinamen hab ich ermittelt und habe das Packet mit require geladen und den Rückgabewert in eine Variable gespeichert. Diese enthält jetzt also den String 'foo'. Jetzt muss ich also aus dem package foo (was für mich als C++ Kenner einen Namespace darstellt) das geladen ist und dessen Name ich als String vorliegen habe die Subroutine getName aufrufen.

Mit
Code: (dl )
&{$wanted}->(@parameter);

kann ich leider nicht viel anfangen. Sorry aber Perl ist abseits von simplen Textkonvertern noch ein Buch mit sieben Siegeln für mich.\n\n

<!--EDIT|mood42|1140786333-->
betterworld
 2006-02-25 02:02
#7018 #7018
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Ich wuerde im Hauptscript (oder einem speziellen Modul) eine Funktion bieten, mit der sich ein Modul registrieren kann. Alle Module, die sich registrieren, werden per Name in einem Array oder so gespeichert. Und in den ganzen Modul-Dateien wird dann einfach diese Registrierfunktion aufgerufen.
renee
 2006-02-25 02:06
#7019 #7019
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Ich habe jetzt mal was schnell geschrieben. Das auslesen der Dateinamen der Module solltest Du aber mit CPAN:File::Find machen.

So ungefaehr sollte es gehen:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/perl

use strict;
use warnings;
use lib qw(.);
use CGI::Carp qw(fatalsToBrowser);

print "Content-type: text/html\n\n";

opendir(DIR,"./Perl") or die $!;
my @pm_files = grep{/\.pm$/}map{"./Perl/".$_}readdir(DIR);
closedir DIR;

for my $module(@pm_files){
require $module;
}

my $module_i_want_to_use = "Perl::Test";

my $subroutine = $module_i_want_to_use."::get_name";

{
no strict 'refs';
&{$subroutine}();
}


und das Modul:
Code: (dl )
1
2
3
4
5
6
7
package Perl::Test;

sub get_name{
print "Hallo";
}

1;


Das $module_i_want_to_use musst Du natuerlich nicht vorbelegen, sondern kannst das auch dynamisch machen.

Ich habe hier das Content-type drin, weil ich den Code auf einem Webserver getestet habe (sitze hier an ner Gurke ohne Perl)...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
<< |< 1 2 >| >> 12 Einträge, 2 Seiten



View all threads created 2006-02-23 16:14.