2014-03-24 7 views
5

Ich war in letzter Zeit auf einer "Putzstunde" bei der Arbeit und habe eine Menge Ausbesserungsarbeiten gemacht, die schon vor einer Weile erledigt sein sollten. Eine Sache, die ich gemacht habe, ist gelöschte Module, die in Dateien importiert und nie benutzt wurden, oder sie wurden an einem Punkt verwendet, aber nicht mehr. Um dies zu tun, habe ich gerade einen Import gelöscht und die Testdatei des Programms ausgeführt. Was bekommt wirklich, wirklich langweilig.Wie kann ich feststellen, ob ein Perl-Modul tatsächlich in meinem Programm verwendet wird?

Gibt es einen programmatischen Weg, dies zu tun? Kurz von mir selbst ein Programm zu schreiben, um es zu tun.

+2

Ich habe eine ähnliche Reinigung zuvor versucht, und es gibt keine einfache Möglichkeit, es zu tun, wenn Programmierer auf einem importierten Modul '@ EXPORT 'Standard verlassen. Ich versuche, Leute immer dazu zu ermutigen, ein explizites 'use Module qw (list);' - Format zu verwenden, da es Code selbstdokumentierender macht, aber auch, weil es diese Art der Bereinigung viel einfacher macht. – Miller

+0

@Miller, ja das ist definitiv ein Teil des Problems. Manchmal kann ich nicht sagen, woher eine Funktion kommt. –

+0

Vielleicht können Sie jede Funktion automatisch in alle geladenen Module einbinden und den Modulnamen im Wrapper ausdrucken. – perreal

Antwort

3

Kurze Antwort, können Sie nicht.

Längere möglicherweise nützlichere Antwort, Sie werden nicht ein Allzweck-Tool finden, das Ihnen mit 100% Sicherheit sagen wird, ob das Modul, das Sie löschen, tatsächlich verwendet wird. Möglicherweise können Sie jedoch ein spezielles Tool erstellen, das Sie bei der manuellen Suche unterstützt, die Sie gerade in Ihrer Codebasis durchführen. Versuchen Sie vielleicht einen Wrapper um Ihre Testsuite herum, der die Benutzungsanweisungen für Sie entfernt und alle Fehlermeldungen ignoriert, mit Ausnahme der Meldungen Undefined subroutine &__PACKAGE__::foo und anderer Meldungen, die beim Zugriff auf fehlende Funktionen eines Moduls auftreten. Der Wrapper könnte dann automatisch eine dumme Quellensuche an der Codebasis des Moduls durchführen, das gelöscht wird, um zu sehen, ob das fehlende Unterprogramm foo (oder ein anderes Merkmal) in dem unerwünschten Modul definiert sein könnte.

Sie können dies mit Devel :: Cover ergänzen, um festzustellen, welche Teile Ihres Codes keine Tests enthalten. Sie können diese Bereiche manuell überprüfen und erhalten möglicherweise einen Einblick, ob sie Code aus dem Modul verwenden, das Sie versuchen säubern.

Aufgrund der halting problem können Sie nicht statisch feststellen, ob ein Programm mit ausreichender Komplexität beendet wird oder nicht. Dies trifft auf Ihr Problem zu, da die "letzte" Anweisung Ihres Programms diejenige ist, die das zu löschende Modul verwendet. Und da es unmöglich ist zu bestimmen, was die letzte Anweisung ist oder ob sie jemals ausgeführt wird, ist es unmöglich, statisch zu bestimmen, ob diese Baugruppe verwendet wird. In einer dynamischen Sprache, die das Programm während seiner Ausführung erweitern kann, würde eine Analyse der Quell- oder sogar der Nach-Kompilierung-Symboltabellen nur sagen, was das unerwünschte Modul gerade vor der Laufzeit aufgerufen hat (was auch immer das bedeutet).

Aus diesem Grund finden Sie kein allgemeines Werkzeug, das für alle Programme funktioniert. Wenn Sie jedoch sicher sind, dass Ihr Code bestimmte Laufzeitfunktionen von Perl nicht verwendet, können Sie möglicherweise ein für Ihr Programm geeignetes Werkzeug schreiben, das feststellen kann, ob Code aus dem Modul, das Sie bereinigen, tatsächlich ausgeführt wird.

1

Sie können alternative Versionen der fraglichen Module erstellen, in denen nur eine AUTOLOAD-Methode (und Import, siehe Kommentar) enthalten ist. Machen Sie diese AUTOLOAD-Methode bei der Verwendung krächzen. Setzen Sie dieses Modul zuerst in den Include-Pfad.

Sie können diese Methode verfeinern, indem Sie AUTOLOAD nur die Verwendung protokollieren und dann das echte Modul laden und den ursprünglichen Funktionsaufruf weiterleiten. Sie könnten auch eine Unterroutine in @INC haben, die das gefälschte Modul bei Bedarf erzeugt.

Natürlich brauchen Sie eine gute Testabdeckung, um auch seltene Anwendungen zu erkennen.

Dieses Konzept ist definitiv nicht perfekt, aber es könnte mit vielen Modulen funktionieren und das Testen vereinfachen.

+0

bedeutet Laden die Verwendung? – perreal

+0

Ok, vielleicht solltest du nicht nur die AUTOLOAD-Methode, sondern auch die Importmethode definiert haben (und vielleicht Dummy-Funktionen für alles hinzufügen, was der Benutzer zu importieren versucht), damit es sich bei der Verwendung nicht schon beschweren wird. –

+0

Das ist wirklich nicht besser, als nur die Anweisung 'use' zu ​​entfernen und dann den Code zu testen, um zu sehen, ob er bricht. Es ist ein Glück, dass er tatsächlich Testsuites für einige seiner Module hat, da dies nicht immer der Fall ist. Was auch immer, er wird versuchen müssen, den Code so gründlich wie möglich zu testen. Es wäre nur schön, wenn es eine einfache Möglichkeit gäbe, Risiken zu bewerten. – Miller

Verwandte Themen