2016-07-31 8 views
2

Ich glaube, die kanonische Weise der Eltern Klasse Konstruktor in Perl zu nennen ist:Wie rufe ich den Konstruktor des Großelterns auf (weil der Konstruktor des Elternteils nicht definiert ist)?

package Child; 
our @ISA = 'Parent'; 

sub new { 
    my $class = shift; 
    my @args = @_; 
    my $self = $class->SUPER::new(@args); 
    return $self; 
} 

jedoch dieses Konstrukt scheint nicht zu funktionieren, wenn Parent nicht explizit eine Definition new Funktion (aber Grandparent tut) .

Dies ist zum Beispiel der Fall mit Net::FTP::File.

tq84_ftp.pm:

package tq84_ftp; 

use warnings; 
use strict; 

our @ISA = qw(Net::FTP::File); 

sub new { 
    my $class = shift; 
    my $self = $class->SUPER::new('localhost') 
    or die([email protected]); 
    return $self; 
}  

1; 

script.pl:

use tq84_ftp; 
tq84_ftp->new(); 

Ausgang:

Can't locate package Net::FTP::File for @tq84_ftp::ISA at tq84_ftp.pm line 10. 
Can't locate package Net::FTP::File for @tq84_ftp::ISA at tq84_ftp.pm line 10. 
Can't locate object method "new" via package "tq84_ftp" at tq84_ftp.pm line 10. 

Wie kann ich angeben, dass ich Perl die richtige (hier: grantparent ist) finden wollen new Funktion ?

+1

Sie sollten wirklich nicht diese fragen. Natürlich ist es möglich, da die meisten Dinge in Perl sind. Aber das Design Ihrer Klassenstruktur ist sehr fehlerhaft und Sie sollten nicht Code schreiben, um es zu umgehen. – Borodin

+0

Sie können mir sicherlich helfen, mich darauf hinzuweisen, was ich stattdessen fragen sollte. –

+0

Sie benötigen Hilfe bei Ihrer Klassenstruktur. Wenn Sie wirklich nicht wissen, wie Sie vorgehen sollen, müssen Sie Ihren gesamten relevanten Code veröffentlichen. Höchstwahrscheinlich müssen Sie einen Auftragnehmer beschäftigen. Wenn es nur eine oder zwei Klassen gibt, können wir Ihnen vielleicht helfen, wenn Sie alles zeigen, was Sie haben, aber ich denke, das ist unwahrscheinlich. – Borodin

Antwort

5

Es scheint, dass Sie davon ausgehen, dass Net::FTP::File ist eine Unterklasse von Net::FTP und daher

my $self = $class->SUPER::new('localhost') ... 

aufrufen sollte Net::FTP ‚s new Methode.

jedoch in der Tat Net::FTP::Filenicht vererben Net::FTP. Stattdessen definiert es einige Methoden in neu. Wenn Ihre Klasse von Net::FTP::File erbt, wird es daher kein Kind von Net::FTP sein.

Sie können dies leicht sehen, wenn Sie die source code for Net::FTP betrachten. Beachten Sie, dass es keine use base 'Net::FTP' oder use parent 'Net::FTP' oder our @ISA = qw(Net::FTP) unter:

package Net::FTP::File; 

use strict; 
use warnings; 
use Net::FTP; 

# ... 

sub Net::FTP::pretty_dir { 
    shift; 
    my $newp = shift; 
    if (defined $newp) { 
     $pretty = $newp; 
     $DirProcHash{cols} = $cols{pretty} if $pretty; 
     $DirProcHash{cols} = $cols{utility} if !$pretty; 
    } 
    return $pretty; 
} 

# ... 

sub Net::FTP::isfile { 
    my $ftp = shift; 
    return 1 if $ftp->exists(@_) && !$ftp->isdir(@_); 
    0; 
} 

etc etc.

6

jedoch dieses Konstrukt scheint nicht zu funktionieren, wenn Parent nicht explizit eine neue Funktion definieren (aber Grandparent tut).

Nicht wahr.

$ perl -E' 
    package Grandparent { 
     sub new { CORE::say(__PACKAGE__) } 
    } 

    package Parent { 
     our @ISA = "Grandparent"; 
    } 

    package Child { 
     our @ISA = "Parent"; 
     sub new { my $class = shift; $class->SUPER::new(); } 
    } 

    Child->new(); 
' 
Grandparent 

Can't locate package Net::FTP::File

Dies ist eine Warnung erhalten, wenn Sie versuchen, von einer Klasse zu erben, die nicht deklariert wurde. Insbesondere versuchen Sie, Net :: FTP :: File zu verwenden, ohne es geladen zu haben. Ersetzen

our @ISA = 'Net::FTP::File'; 

mit

use Net::FTP::File qw(); 
our @ISA = 'Net::FTP::File'; 

oder mit

use parent 'Net::FTP::File'; 

Can't locate object method "new" via package "tq84_ftp"

Diese Nachricht ist ein wenig unklar, aber es ist aufgrund der Tatsache, dass Net::FTP::File->new existiert nicht. Net :: FTP :: File ist keine Klasse, geschweige denn eine Unterklasse von Net :: FTP. Es hat keine Methoden, geschweige denn eine Methode. Es macht keinen Sinn, von Net :: FTP :: File zu erben.

Sie scheinen zu wollen, ein Net :: FTP-Objekt zu erstellen, so ersetzen

use parent 'Net::FTP::File'; 

mit

use parent 'Net::FTP'; 

Schließlich Sie Net :: FTP :: Datei laden möchten für die Methoden, die es zu Net :: FTP-Objekten hinzufügt (die Objekt von Klassen enthalten, die von Net :: FTP erben). Um dies zu tun, fügen Sie einfach

use Net::FTP::File qw(); 
+0

Zu meiner Antwort hinzugefügt. Bitte geben Sie in der Zukunft Code ein, den Sie tatsächlich ausgeführt haben, und geben Sie die tatsächliche Ausgabe aus diesem Code an. – ikegami

+0

@ikegame Danke für die Mühe, die Sie gestellt haben, um meine Frage zu beantworten. Nach einem Tag zu lange habe ich einen schlampigen Fehler gemacht, obwohl ich sicher war, dass ich die richtige Fehlermeldung kopiere/eingefügt habe. Wie auch immer, ich werde es nächstes Mal besser machen. –

Verwandte Themen