2016-10-14 4 views
0

Ich versuche, 2 Arrays und einen Verweis auf ein Unterprogramm zu übergeben. Es funktioniert gut für die Arrays, aber nicht für die Referenz "$ plistref". Wenn ich versuche, es so in der Subroutine zu verwenden, wie ich es vorher benutzt habe, funktioniert es nicht.Perl mit Bezug auf Subroutine

... 
    my $locPlist = "conf.plist"; 
    my $configdict = NSDictionary->dictionaryWithContentsOfFile_($locPlist); 
    my $plistref = Foundation::perlRefFromObjectRef($configdict); 

    my @contentMatchs; 
    foreach (@{ $plistref->{content_match} }) { 
     push @contentMatchs, $_->{match}; 
    } 

    .... 

    # Process the files 
    _moveFile(\@files, \@contentMatchs, \$plistref); 
} 

sub _moveFile { 
    my ($files_ref, $contentMatchs_ref, $plistref_ref) = @_; 

    my @files   = @{ $files_ref }; 
    my @contentMatchs = @{ $contentMatchs_ref }; 
    my $plistref  = $plistref_ref; 

    my @spools = @{ $plistref->{SPOOLS} }; 
.... 
} 

Es sagt mir für die letzte Zeile, dass „kein Hashreferenz ..“ ich nicht herausfinden kann, wie man diese ref durch das Unterprogramm zu übergeben.

EDIT: Ich habe versucht einen Workaround mit "shift" und es hat funktioniert! Es scheint nicht die beste Option tho

_moveFile($plistref, \@files, \@contentMatchs); 
} 

sub _moveFile { 
    my $plistref  = shift; 

    my ($files_ref, $contentMatchs_ref) = @_; 
    my @files   = @{ $files_ref }; 
    my @contentMatchs = @{ $contentMatchs_ref }; 

Vielen Dank für Ihre Hilfe!

-Tim.

+0

Ich habe das bereits versucht, $ plistref gibt "1" in der Subroutine zurück:/ – Thomas

+0

$ plistref ist ein HASH tho – Thomas

+0

Ich rollte die Bearbeitung zurück, die alle Details aus dieser Frage entfernte. Bitte tu das nicht, da es fast unmöglich ist, die Antworten zu verstehen. –

Antwort

0

\$plistref ist ein Verweis auf einen Skalar. Dereferenzieren es in der Funktion, müssen Sie

my $plistref  = ${ $plistref_ref }; 
2

_moveFile(\@files, \@contentMatchs, \$plistref); hier sagen, Sie sind eine Referenz auf ein hashref als drittes Argument übergeben. Das heißt, ein Verweis auf einen Verweis auf einen HASH. Sie brauchen das HASHREF nicht als Referenz zu übergeben, da es bereits eins ist. Das heißt, rufen Sie Ihre Unterprogramm wie folgt aus: _moveFile(\@files, \@contentMatchs, $plistref);

Wenn aus irgendeinem Grund, Sie einen Verweis auf eine hashref, passieren wollte man konnte dereferenzieren den Wert wie folgt aus: ${$plistref}->{SPOOLS}.

_moveFile($plistref, \@files, \@contentMatchs); Hier übergeben Sie in Ihrer Bearbeitung ein HASHREF als erstes Argument. Aus diesem Grund funktioniert die Verwendung von my $plistref = shift - die Variable hat den erwarteten Referenzierungsgrad.

2

Ihr "Workaround" hat ein paar Dinge geändert. Ursprünglich Sie dies hatte:

_moveFile(\@files, \@contentMatchs, \$plistref); 

Und im Unterprogramm, das:

sub _moveFile { 
    my ($files_ref, $contentMatchs_ref, $plistref_ref) = @_; 

nach dem Problem zu umgehen, zeigen Sie uns dies:

_moveFile($plistref, \@files, \@contentMatchs); 

Und im Unterprogramm, diese:

sub _moveFile { 
    my $plistref  = shift; 
    my ($files_ref, $contentMatchs_ref) = @_; 

Sie sagen tha t du "versucht einen Workaround mit shift und es hat funktioniert!" Aber es ist nicht die Umstellung auf shift, die das Problem behoben. Es war der Wechsel von \$plistref zu passieren $plistref.

Sie haben offensichtlich herausgefunden, dass es eine gute Idee ist, Arrays und Hashes mithilfe von Referenzen in Subroutinen zu übergeben. Und das ist großartig. Aber was Sie nicht bemerkt haben, ist, dass $plistref bereits eine Referenz ist, so dass Sie keinen Verweis darauf erneut benötigen. Wenn Sie \$plistref in Ihrem ursprünglichen Code übergeben, übergeben Sie einen Verweis auf einen Skalar mit einem Verweis auf einen Hash. Also war es richtig, dass Perl Ihnen sagte, dass es "keine HASH-Referenz" war.

So können Sie zurück zu den meisten Ihrer ursprünglichen Code, nur das eigentliche Problem beheben.

_moveFile(\@files, \@contentMatchs, $plistref); 

Und im Unterprogramm, das:

sub _moveFile { 
    my ($files_ref, $contentMatchs_ref, $plistref_ref) = @_; 

Und alles funktioniert, wie Sie wollen. Die shift war eine komplette Hering.

Verwandte Themen