Open Source im professionellen Einsatz

Newsletter abonnieren
Seite durchsuchen

HEFTARCHIV | NEWS | E-BIBLIOTHEK | VIDEO | BLOGS | WHITEPAPER | EVENTS | ACADEMY | ABO | SHOP

user friendly

  Home  »  Heft & Abo  »  Heftarchiv  »  2005  »  07  »  Tipps für Tippfaule  

RSS-Feed der aktuellen News von Linux-Magazin Online Folgen Sie Linux-Magazin Online auf Twitter
Diesen Artikel druckenDiesen Artikel weiterempfehlen Diesen Artikel kommentieren Newsletter abonnieren
Share/Bookmark

Sprungziele

Um Vim dazu zu veranlassen, auch in Perl etwa zur Source-Datei von »LWP::UserAgent« zu springen, falls der Cursor irgendwo auf »LWP::UserAgent« steht, muss der Anwender zwei Dinge erledigen. Zuerst muss Vim verstehen, dass in Perl ein Schlüsselwort auch Doppelpunkte enthalten kann, das bewerkstelligt »:set iskeyword+= :«. Zweitens muss Vim noch eine Tags-Datei einlesen, die alle installierten Packages indiziert hat, zum Beispiel über »:set tags=/home/mschilli/.ptags.txt«. Dann springt die Kombination [Ctrl]+[]] in den Modul-Source, wenn der Cursor auf einem Modulnamen steht.

Alternativ kann man den Modulnamen auch im Kommando »:tag LWP::UserAgent« angeben. Einmal in der Bibliotheksdatei angelangt genügt ein [Ctrl]+[Shift]+[T], um wieder zurück zum Ausgangspunkt zu navigieren. Die ganze Magie steckt dabei in der Tags-Datei ».ptags.txt«, die das weiter unten vorgestellte Listing »ppitags« erzeugt.

Trotz Windowmanager ist es manchmal sinnvoll, zwei Dateien gleichzeitig in einem Fenster zu sehen. Welcher Vim-User greift schon freiwillig auf die Maus zurück, wenn die Hände auf der Tastatur bleiben können? Wer statt [Ctrl]+[]] die Kombination [Ctrl]+[W]+[]] tippt, während der Cursor auf einem Schlüsselwort steht, dessen Fenster teilt sich in zwei Hälften: In der unteren bleibt der Code der editierten Datei sichtbar, in der oberen erscheint der Code des referenzierten Moduls.

Zwischen den Fensterhälften springt man mit [Ctrl] und zweimal [W] hin und her. Das Kommando »:quit« im oberen Fenster schließt dieses. Alternativ schließt der Befehl »:only« im unteren Fenster das obere. Die Vim-Session in Abbildung 6 zeigt unten ein editiertes Testskript, das das Modul »LWP::UserAgent« verwendet, und oben die »new()«-Methode im Sourcecode des Moduls.


Abbildung 6: Vim mit gespaltenem Fenster: Unten ein Testskript, oben der Sourcecode des verwendeten Moduls »LWP::UserAgent«.

Wer den Namen eines gesuchten Moduls nicht genau weiß, gibt einen regulären Ausdruck an. Das Kommando »tselect« sucht nach allen passenden Tags und bietet eine Liste zur Auswahl: »:tselect /^LWP«. Der Benutzer muss dann nur den passenden Treffer per Nummernmenü auswählen.

Mach mir Tags

Für ein aktuelles »~/.ptags.txt«-File muss ein Skript regelmäßig alle Module der lokalen Perl-Installation durchforsten. Das Skript »ppitags« in Listing 1 klappert alle »@INC«-Pfade ab, merkt sich in »@dirs«, wo es bereits war, und durchläuft auch bei überlappenden Pfaden nicht zweimal denselben.

Listing 1:
»ppitags«

01 #!/usr/bin/perl -w
02 
03 use strict;
04 
05 use PPI::Document;
06 use File::Find;
07 use Sysadm::Install qw(:all);
08 use Log::Log4perl qw(:easy);
09 
10 my $outfile = "$ENV{HOME}/.ptags.txt";
11 my %dirs  = ();
12 my @found = ();
13 
14 find &file_wanted, grep {$_ ne "."} @INC;
15 
16 blurt join("n", sort @found), $outfile;
17 
18 ###########################################
19 sub file_wanted {
20 ###########################################
21     my $abs = $File::Find::name;
22 
23         # Avoid dupe dirs
24     $File::Find::prune = 1 if -d and
25         $dirs{$abs}++;
26 
27         # Only Perl modules
28     return unless /.pm$/;
29 
30     my $d = PPI::Document->load($abs);
31 
32     unless($d) {
33         WARN "Cannot load $abs ($! $@)";
34         return;
35     }
36         # Find packages and
37         # all named subroutines
38     $d->find(&document_wanted);
39 }
40 
41 ###########################################
42 sub document_wanted {
43 ###########################################
44     our $package;
45     my  $tag;
46 
47     if(ref($_[1]) eq
48            'PPI::Statement::Package') {
49         $tag = $_[1]->child(2)->content();
50         $package = $tag;
51 
52     } elsif(ref($_[1]) eq
53             'PPI::Statement::Sub' and
54             $_[1]->name()) {
55         $tag = "$package::" .
56                $_[1]->name();
57     }
58 
59     return 1 unless defined $tag;
60 
61     push @found, $tag . "t" .
62                  $File::Find::name . "t" .
63                  regex_from_node($_[1]);
64 
65     return 1;
66 }
67 
68 ###########################################
69 sub regex_from_node {
70 ###########################################
71     my($node) = @_;
72 
73     my $regex = $node->content();
74 
75     $regex =~ s/n.*//gs;
76 
77     while(my $prev =
78              $node->previous_sibling()) {
79         last if $prev =~ /n/;
80         $regex = $prev->content() .
81                  $regex;
82         $node  = $prev;
83     }
84 
85     $regex =~ s#[/.*[]^$]#\$&#g;
86     return "/^$regex/";
87 }

Um Perl-Source zu analysieren, braucht man eigentlich Perl, denn Perl ist extrem schwierig zu parsen. Allerdings hat Adam Kennedy vor kurzem das Unmögliche gewagt und einen "Good enough"-Parser für Perl geschrieben, der wirklich erstaunlich gut arbeitet. Das »PPI«-Modul vom CPAN enthält »PPI::Document«, dessen Methode »load()« ein Perl-Modul einliest, in Tokens zerlegt und in einer Baumstruktur ablegt.

Das Skript »ppitags« nutzt »File::Find«, um alle Verzeichnisse in Perls globalem Array »@INC« zu durchlaufen. Für jeden gefundenen Eintrag springt »File::Find« die Funktion »file_wanted« an. Falls der gefundene Eintrag ein Verzeichnis und keine Datei ist, frischt Zeile 25 den Hash »%dirs« auf, um festzustellen, ob das Skript den Pfad schon besucht hat. Falls ja, setzt Zeile 24 die Variable »$File::Find::prune« auf »1«, um »File::Find« mitzuteilen, dass es sich den Rest des Verzeichnisses und alle Unterverzeichnisse sparen kann. Zeile 28 weist alles außer Perl-Modulen mit der Endung ».pm« zurück. Zeile 30 parst das gefundene Perl-Modul. Falls dabei Fehler auftreten, fängt Zeile 32 sie ab, gibt eine Warnung aus und lässt das problembehaftete Modul sausen.

Konnte das Modul erfolgreich eingelesen werden, ruft Zeile 38 die »find()«-Methode des »PPI::Document«-Objekts auf, das die Tokens der Perl-Source durchläuft und für jeden gefundenen die ab Zeile 42 definierte Funktion »document_wanted« aufruft. Diese prüft, ob es sich bei dem gefundenen Token um ein Objekt vom Typ »PPI::Statement::Package« oder »PPI::Statement::Sub« handelt, also eine »package«- oder »sub«-Definition im Perl-Code.

Eine »package«-Definition besteht aus einer Zeile wie »package LWP::UserAgent;«, das sind in der PPI-Welt vier Tokens: »package«, Leerzeichen, der Modulname und der abschließende Strichpunkt. Für die Belange von »ppitags« ist nur der Modulname interessant, also das dritte Kind des Knotens, der in »$_[1]« übergeben wurde. Die Methode »child()« mit dem ab 0 gezählten Kinder-Index fördert den String »"LWP::UserAgent"« zutage: »$_[1]->child(2)«.

Diesen Artikel druckenDiesen Artikel weiterempfehlen Diesen Artikel kommentieren Newsletter abonnieren
Share/Bookmark
Ähnliche Artikel
Umlaute auf Umwegen Ein Blick hinter die Kulissen der Zeichensätze und Kodierungen
Muschelperle Shell-Funktionen in Perl nachgebaut
Übersetzungskünstler Parser im Eigenbau mit Perl
Füttern nach Programm Tipps täglich verschicken
Prüfungsfrage Vim-Makros in Perl schreiben
Babylon zu fünft Populäre Programmiersprachen treten gegeneinander an
Whitepaper
Daten Migration - Eine Publikation von Bloor Research

Datenmigrationsprojekte überschreiten häufig das Budget, neigen zu Verzögerung und werden unter Umständen komplett abgebrochen. Bloor Research ist eines der weltweit führenden IT-Forschungs-, Analyse- und Beratungsunternehmen und wird in dem vorliegenden White Paper die wichtigsten Aspekte dieser Problematik näher beleuchten. Ferner werden praktische Empfehlungen für erfolgreiche Migrationsprojekte gegeben, die Sie auf Ihr nächstes Projekt übertragen können.

Download PDF (Registrierung erforderlich)
Open Source Datenintegration in der Praxis: Fallstudien und Anwendungsbeispiele

Über die letzten Jahre hinweg haben sich Open Source Lösungen als fester Bestandteil des gesamten Datenintegrationsmarktes etabliert. Viele Unternehmen haben bereits das Open Source Modell für Ihre Datenintegrationsprojekte aufgegriffen. Das vorliegende White Paper illustriert anhand ausgewählter Fallstudien und Anwendungsbeispiele die Implementierung von Open Source Datenintegration in der Praxis und benennt die daraus resultierenden Vorteile.

Download PDF (Registrierung erforderlich)
Kommentare (0)