Anzeige:
Ergebnis 1 bis 4 von 4

Thema: [Perl] "Forwarding" von Funktionen via AUTOLOAD

  1. #1
    illu
    Gast

    [Perl] "Forwarding" von Funktionen via AUTOLOAD

    Hi,

    als erstes gleich mal der (auf's Wesentliche reduzierte) Code:

    Code:
    package UI;
    
    use Curses;
    
    sub new { bless {}, shift }
    
    sub AUTOLOAD {
        my ($self, @args) = @_;
    
        use vars qw($AUTOLOAD);
    
        print "$AUTOLOAD(@args)\n";    # gibt beim Testen "UI::DESTROY()" aus, und nicht, wie erwartet, "UI::initscr()"?
        $AUTOLOAD =~ s/.*:://;
    
        eval "$AUTOLOAD(@args)";       # oder "Curses::$AUTOLOAD"; ? Hat beim Testen keinen Unterschied gemacht
    }
    
    package main;
    
    my $ui = UI->new();
    $ui->initscr();
    # usw.
    Ich wuerde also gerne in der UI-Klasse nicht definierte Methodenaufrufe direkt an Curses.pm "weiterleiten".
    Bei dem Programm, was ich gerade schreibe, moechte ich also einfach alles UI-maessige ueber meine UI-Klasse machen, also auch die Interaktion mit Curses.
    (Zwischenfrage: ist das ueberhaupt eine gute Idee so, in Hinblick auf gutes Programmdesign, oder sollte ich es ganz anders angehen?)

    Wieso funktioniert es aber nicht so wie oben?
    Beim Testen (mit "use warnings") die()t es mit der folgenden Ausgabe:

    Code:
    Curses function 'initscr' called with too many arguments at ./test.pl line n.
    Geändert von illu (23-06-2005 um 19:34 Uhr)

  2. #2
    Registrierter Benutzer
    Registriert seit
    19.08.2004
    Beiträge
    404
    Hi,

    # gibt beim Testen "UI:ESTROY()" aus, und nicht, wie erwartet, "UI::initscr()"?
    halbe Wahrheit

    Wenn Du in MAIN ein UI-Objekt erzeugst, dann wird am Ende von MAIN bzw. am Ende des blockes, in dem das Objekt erzeugt wurde IMMER versucht, einen Destruktor aufzurufen. ->DESTROY(). Der Unterschied zu anderen Methoden ist, dass es keinen Syntaxfehler gibt, wenn diese Methode nicht existiert.

    Insgesamt hast Du als 3 Methoden Aufrufe:

    UI->new()
    UI->initscr();
    UI->DESTROY();

    Die Destroy Methode solltest Du auf jeden Fall noch in der UI Klasse implementieren - kann ja leer sein. Andernfalls würde der Autoloader versuchen, die Methode von Curses aufzurufen, was vermutlich nicht gewünscht ist

    Ansonsten versuch doch mal statt

    use Curses;

    use lib Curses;

    zu benutzen...


    # oder "Curses::$AUTOLOAD"; ? Hat beim Testen keinen Unterschied gemacht
    Besser Curses::$AUTOLOAD, denn sonst funktioniert das nur mit Methoden, die von Curses exportiert werden...

    hth, michael

  3. #3
    illu
    Gast
    Ok, das mit der leeren DESTROY-Funktion ist eine gute Idee dann.
    Aber das Seltsame ist ja, dass print ueberhaupt kein "initscr" ausgibt, sondern *nur* das "DESTROY".
    Ansonsten hilft leider nichts von dem, was du sagtest. Sonst noch eine Idee? Wenn nicht, muss ich's halt anders machen.
    Geändert von illu (25-06-2005 um 09:00 Uhr)

  4. #4
    Registrierter Benutzer
    Registriert seit
    19.08.2004
    Beiträge
    404
    Aber das Seltsame ist ja, dass print ueberhaupt kein "initscr" ausgibt, sondern *nur* das "DESTROY".
    Ne - das ist richtig so. curses exportiert die initscr() Methode - das bedeutet, sie ist jetzt in UI verfügbar. Der AUTOLOADER greift also nicht.

    Aber genau da liegt glaubich auch das Problem...
    vergiss das mit dem "use lib Curses".
    Ehrlichgesagt kam es mir auch schon ein wenig komisch vor, denn damit beeinflusst man eigentlich nur die Reihenfolge, in der die Module geladen werden.
    Versuch doch mal so:

    Code:
    package UI;
    
    use Curses qw();
    
    sub new { bless {}, shift }
    
    sub AUTOLOAD {
        my $self = shift(@_);
        my @args = @_;
        $" = ',';
    
        our $AUTOLOAD;
        $AUTOLOAD =~ s/.*:://;
        print "Method UI::$AUTOLOAD(@args) not found...forwarding!\n";
        eval("Curses::$AUTOLOAD(@args)");
    }
    
    sub DESTROY 
    {
      print "Destruktor...\n";
    }
    
    package main;
    
    my $ui = UI->new();
    $ui->initscr();

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •