Was ist eine indirekte Objektnotation, warum ist sie schlecht und wie vermeidet man sie?

8

Der Titel fasst es ziemlich zusammen, aber hier ist sowieso die lange Version.

Nachdem ich einen kleinen Code mit Perl geschrieben hatte, wurde mir gesagt, ich solle die indirekte Objektnotation vermeiden, "da sie mehrere Nebenwirkungen hat". Der Kommentar verweist auf diese bestimmte Zeile:

%Vor%

Da ich es immer so gemacht habe, um in die Zeit zu kommen, frage ich:

  • Was ist daran so schlimm? (speziell)
  • Was sind die möglichen (vermutlich negativen) Nebenwirkungen?
  • Wie sollte diese Zeile neu geschrieben werden?

Ich wollte den Kommentator fragen, aber für mich ist das eine eigene Aufgabe wert.

    
Jarmund 05.10.2015, 18:15
quelle

4 Antworten

17

Das Hauptproblem ist, dass es nicht eindeutig ist. Ist

%Vor%

bedeutet, die Methode new im Paket Some::Module aufzurufen oder die Funktion new im aktuellen Paket aufzurufen, mit dem Ergebnis, dass die Funktion Module im Paket Some aufgerufen wird die gegebenen Parameter?

d. h., es könnte geparst werden als:

%Vor%

Die Alternative besteht darin, die explizite Methodenaufrufnotation Some::Module->new(...) .

zu verwenden

Normalerweise nimmt der Parser eine korrekte Vermutung an, aber die beste Vorgehensweise besteht darin, die Mehrdeutigkeit zu vermeiden.

    
cjm 05.10.2015, 18:21
quelle
9
  

Was ist daran so schlimm?

Die Probleme mit der indirekten Methodennotation sind vermeidbar, aber es ist viel einfacher, den Leuten zu sagen, dass sie die Indirekte Methodennotation vermeiden sollten.

Das Hauptproblem ist, dass es sehr einfach ist, versehentlich die falsche Funktion aufzurufen. Nehmen Sie den folgenden Code, zum Beispiel:

%Vor%

In diesem Code wird erwartet, dass new SubWidget

bedeutet %Vor%

Stattdessen bedeutet es eigentlich

%Vor%

Das heißt, die Verwendung von strict wird die meisten dieser Instanzen dieses Fehlers erfassen. Wenn use strict; zum obigen Snippet hinzugefügt würde, würde der folgende Fehler erzeugt:

%Vor%

Das heißt, es gibt Fälle, in denen die Verwendung von strict den Fehler nicht erfassen würde. Sie beinhalten hauptsächlich die Verwendung von Parens um die Argumente des Methodenaufrufs (z. B. new SubWidget($x) ).

Das heißt also

  • Indirekte Objektnotation ohne Parens kann zu seltsamen Fehlermeldungen führen.
  • Die Verwendung indirekter Objektnotation mit parens kann dazu führen, dass der falsche Code aufgerufen wird.

Ersteres ist erträglich, letzteres vermeidbar. Aber anstatt den Leuten zu sagen: "Vermeiden Sie Parens um die Argumente von Methodenaufrufen mit Indirekter Methodennotation", sagen wir einfach "Vermeiden Sie die Verwendung der indirekten Methodennotation". Es ist einfach zu zerbrechlich.

Es gibt ein anderes Problem. Es ist nicht nur eine indirekte Objektnotation, sondern ein Problem, das in Perl unterstützt wird. Das Vorhandensein des Features verursacht mehrere Probleme. Hauptsächlich

  • Es führt dazu, dass einige Syntaxfehler zu sehr merkwürdigen / irreführenden Fehlermeldungen führen, da der Code ION zu verwenden scheint, wenn dies nicht der Fall war.
  • Es verhindert, dass nützliche Funktionen implementiert werden, da sie mit der gültigen ION-Syntax kollidieren.

Auf der positiven Seite hilft no indirect; beim ersten Problem.

  

Wie sollte diese Zeile neu geschrieben werden?

Die korrekte Methode zum Schreiben des Methodenaufrufs lautet wie folgt:

%Vor%

Das heißt, auch diese Syntax ist mehrdeutig. Es wird zuerst überprüft, ob eine Funktion namens Some::Module existiert. Aber das ist sehr unwahrscheinlich, dass sich nur sehr wenige Menschen vor solchen Problemen schützen. Wenn Sie sich schützen wollten, könnten Sie Folgendes verwenden:

%Vor%     
ikegami 05.10.2015 18:50
quelle
6

Wie man es vermeidet: Es gibt ein CPAN-Modul, das die Notation verbietet und sich wie ein Pragma-Modul verhält:

%Vor%

Ссылка

    
LeoNerd 05.10.2015 20:55
quelle
4

Der Kommentator wollte nur Some::Module->new(FIELD => 'value'); als Konstruktor sehen.

Perl kann indirekte Objektsyntax für andere leere Wörter verwenden, die wie Methoden aussehen , aber heutzutage schlägt die perlobj -Dokumentation vor, sie nicht zu benutzen.

Das allgemeine Problem dabei ist, dass auf diese Weise geschriebener Code mehrdeutig ist und Perls Parser zum Testen des Namensraums auf z. Überprüfen Sie, ob Sie method Namespace schreiben, ob Namespace :: method existiert.

    
Neil Slater 05.10.2015 18:20
quelle

Tags und Links