Warum erlaubt Perl das Aufrufen von Coderefs für nicht geplottete Datenstrukturen?

8

Beim Ausführen der Anweisung $obj->method(); sagt perldiag , dass Perl wissen muss, zu welchem ​​Paket die Methode gehört . Deshalb muss es gesegnet werden:

  

Die Methode "% s" kann nicht auf der nicht ausgewählten Referenz aufgerufen werden

     

(F) Ein Methodenaufruf muss wissen, in welchem ​​Paket er ausgeführt werden soll. Es   findet dies normalerweise aus der von Ihnen gelieferten Objektreferenz, aber   Sie haben in diesem Fall keine Objektreferenz angegeben. Eine Referenz ist nicht   eine Objektreferenz, bis sie gesegnet wurde. Sehen    perlobj .

Aus diesem Grund ist Folgendes nicht möglich:

%Vor%

Warum funktioniert es dann mit einer Coderef?:

%Vor%     
Zaid 14.11.2011, 18:29
quelle

3 Antworten

22
%Vor%

ruft nur

auf %Vor%

Aber in welchem ​​Paket sollte Perl das Unterprogramm method finden? Wenn $variable eine gesegnete Referenz ist, sucht Perl nach der Subroutine in dem Paket, das von ref $variable zurückgegeben wird. Wenn $variable eine Zeichenfolge und der Name eines Pakets ist, sucht Perl nach der Unterroutine in diesem Paketnamen.

In Ihrem zweiten Beispiel, wenn Sie

deklarieren %Vor%

Sie haben Perl den Verweis auf den Code gegeben, den Sie aufrufen möchten. Daher weiß Perl, dass er den Aufruf

übernehmen soll %Vor%

und rufen

auf %Vor%

oder

%Vor%

Nur wenn $variable ein nicht geglätteter Verweis ist und der Methodenname nicht in eine Codereferenz aufgelöst werden kann, kann Perl nicht herausfinden, was zu tun ist und punts.

    
mob 14.11.2011, 18:43
quelle
10

Wenn Perl $x->$y sieht, kompiliert es es in etwa wie folgt:

%Vor%

Wenn $y zufällig ein Bareword ist, ist die erste Prüfung immer falsch, und dann führt der Block else einen normalen Methodenaufruf aus.

    
Eric Strom 14.11.2011 19:24
quelle
6

Im ersten Beispiel versuchen Sie, eine Methode einer Array-Referenz nach Namen aufzurufen. Die Array-Referenz hat keine Methoden, daher ist dies nicht einmal sinnvoll.

Im zweiten Beispiel verwenden Sie eine ähnliche Syntax, aber in diesem Fall ist -> nur syntaktischer Zucker zum Aufrufen des rechten Parameters mit dem linken Parameter als erstem Argument; Es ruft keine Instanzmethode auf, sondern ruft einfach eine Subroutine mit dem angegebenen Parameter auf.

    
geoffspear 14.11.2011 18:38
quelle

Tags und Links