ClassLoader - Load classes automatically
use ClassLoader; my $obj = My::Class->new; # loads My/Class.pm
(This module is documented in German)
Müde, use-Anweisungen für das Laden von Perl-Klassen zu schreiben?
use
Dieses Modul reduziert das Laden aller Klassen auf eine einzige Anweisung:
use ClassLoader;
Danach wird jede Klasse automatisch mit ihrem ersten Methodenaufruf geladen. Dies geschieht bei jeder Methode, gleichgültig, ob Klassen- oder Objektmethode.
Man muss keine use-Aufrufe mehr schreiben
Es werden nur die Klassen geladen, die das Programm tatsächlich benötigt
Die Startzeit des Programms verkürzt sich
Das Programm benötigt unter Umständen weniger Speicher, da keine überflüssigen Module geladen werden
Unter einem Klassen-Modul verstehen wir eine pm-Datei, die gmäß Perl-Konventionen eine Klasse definiert, d.h. die
ein Package mit dem Namen der Klasse deklariert,
unter dem Namen des Package gemäß den Perl-Konventionen im Dateisystem abgelegt ist,
ihre Basisklassen (sofern vorhanden) selbständig lädt.
Eine Klasse My::Class wird in einer Datei mit dem Pfad My/Class.pm definiert und irgendwo unter @INC installiert. Sie hat den Inhalt:
@INC
package My::Class; use base qw/<BASECLASSES>/; <METHODS> 1;
Das Laden der Basisklassen-Module geschieht hier mittels use base. Es ist genauso möglich, die Basisklassen-Module per use zu laden und @ISA zuzuweisen, was aber umständlicher ist.
use base
@ISA
Eine pm-Datei, die diesen Konventionen genügt, ist ein Klassen-Modul und wird von ClassLoader automatisch beim ersten Methodenzugriff geladen.
ClassLoader installiert sich als Basisklasse von UNIVERSAL und definiert eine Methode AUTOLOAD, bei der sämtliche Methodenaufrufe ankommen, die vom Perl-Interpreter nicht aufgelöst werden können. Die AUTOLOAD-Methode lädt das benötigte Klassen-Modul und ruft die betreffende Methode auf. Existiert das Klassen-Modul nicht oder enthält es die gerufene Methode nicht, wird eine Exception ausgelöst.
Die AUTOLOAD-Methode, die ClassLoader definiert, ist recht einfach (Fehlerbehandlung hier vereinfacht):
sub AUTOLOAD { my $this = shift; # @_: Methodenargumente my ($class,$sub) = our $AUTOLOAD =~ /^(.*)::(\w+)$/; return if $sub !~ /[^A-Z]/; eval "use $class"; if ($@) { die "Modul kann nicht geladen werden\n"; } unless ($this->can($sub)) { die "Methode existiert nicht\n"; } return $this->$sub(@_); }
Lediglich der erste Methodenaufruf einer (noch nicht geladenen) Klasse läuft über diese AUTOLOAD-Methode. Alle folgenden Methodenaufrufe der Klasse finden direkt statt, also ohne Overhead! Methodenaufrufe einer explizit geladenen Klasse laufen von vornherein nicht über die AUTOLOAD-Methode.
Schlägt das Laden des Moduls fehl oder existiert die Methode nicht, wird eine Exception ausgelöst.
Damit der Ort des Fehlers einfach lokalisiert werden kann, enthält der Exception-Text ausführliche Informationen über den Kontext des Fehlers, einschließlich Stacktrace.
Aufbau des Exception-Texts:
Exception: CLASSLOADER-<N>: <TEXT> Class: <CLASS> Method: <METHOD>() Error: <ERROR> Stack: <STACKTRACE>
Ja, denn die AUTOLOAD-Methode von ClassLoader wird vor dem Laden der Klasse angesprochen. Alle späteren Methoden-Aufrufe der Klasse werden über die Klasse selbst aufgelöst. Wenn die Klasse eine AUTOLOAD-Methode besitzt, funktioniert diese genau so wie ohne ClassLoader.
$this->AUTOLOAD;
Lade Klassen-Modul und führe den Methodenaufruf durch. Die Argumente und der Returnwert entsprechen denen der gerufenen Methode. Schlägt das Laden des Moduls fehl, löst die Methode eine Exception aus (siehe oben).
Die AUTOLOAD-Methode implementiert die Funktionalität des Moduls. Sie wird nicht direkt, sondern vom Perl-Interpreter gerufen, wenn eine Methode nicht gefunden wird.
Der Mechanismus funktioniert nicht, wenn der Modulpfad anders lautet als die Klasse heißt. Solche Module müssen explizit per use geladen werden.
Sind mehrere Klassen in einer Moduldatei definiert, kann das automatische Laden logischerweise nur über eine dieser Klassen erfolgen. Am besten lädt man solche Module auch explizit.
Über Aufruf der Methode import() ist es nicht möglich, ein Modul automatisch zu laden, da Perl bei Nichtexistenz von import() AUTOLOAD() nicht aufruft, sondern den Aufruf ignoriert. Man kann durch $class->import() also nicht das Laden eines Klassen-Moduls auslösen.
Module, die nicht objektorientiert, sondern Funktionssammlungen sind, werden von ClassLoader nicht behandelt. Diese müssen per use geladen werden.
CLASSLOADER-00001: Modul kann nicht geladen werden CLASSLOADER-00002: Methode existiert nicht
Frank Seitz, http://www.fseitz.de/
Copyright (C) Frank Seitz, 2008-2010
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install ClassLoader, copy and paste the appropriate command in to your terminal.
cpanm
cpanm ClassLoader
CPAN shell
perl -MCPAN -e shell install ClassLoader
For more information on module installation, please visit the detailed CPAN module installation guide.