Ich habe eine Frage zu Code-Blöcken in Perl. Gegeben folgender Code:
%Vor%verwendet einen Codeblock als Argument.
Ich könnte es wie folgt umschreiben:
%Vor%Ich versuche herauszufinden, wie dieser Mechanismus funktioniert. Derzeit muss ich eine Art komplexe Sortierfunktion implementieren, die in einem Codeblock chaotisch aussehen würde. Es hängt jedoch von einigen lokalen Variablen ab. Zum Beispiel:
%Vor%aber nehmen wir an, dass die Sortierfunktion komplexer ist, also passt sie nicht sauber in den obigen Code.
Wenn ich versuche, eine Funktion zu verwenden (die lokal im Bereich der for-Schleife definiert ist), bekomme ich immer "Verwendung von nicht initialisierten Werten im Hash-Element".
Ich nehme an, das liegt daran, dass die Subroutine einmal analysiert wird und nicht für jede Wiederholung der for-Schleife neu erstellt wird. Ich versuche zu verstehen, wie man einen Codeblock implementiert, der bei jeder Iteration neu interpretiert wird, oder vielleicht, wie man Parameter weitergibt
Sie haben den problematischen Code aus irgendeinem Grund nicht gezeigt, aber ich denke, es ist etwas wie
%Vor%Ich versuche herauszufinden, wie dieser Mechanismus funktioniert. [...] Ich nehme an, das liegt daran, dass das Subsystem einmal analysiert wird und nicht für jede Wiederholung der for-Schleife neu erstellt wird.
Nicht ganz. Das Folgende analysiert und kompiliert das Sub nur einmal, aber es funktioniert:
%Vor% Was zählt ist, wenn was $val
erfasst wird. $val
wird erfasst, wenn sub { ... }
ausgewertet wird. Beachten Sie, dass
ist in dieser Hinsicht das gleiche wie das Folgende,
%Vor% In meinem Code wird die $val
von der foreach-Schleife erfasst. In Ihrem Fall wird es zur Kompilierzeit erfasst, sodass es die $val
erfasst, die zur Kompilierungszeit vorhanden war. Und das ist nicht die Variable, die Sie wollen.
Nun, da Sie wissen, wie Sie es zum Laufen bringen können, können Sie den komplexen Code nach Belieben aus dem Weg schieben (out of the loop).
%Vor%Alternativ können Sie die erforderlichen Werte an die Vergleichsfunktion übergeben, anstatt sie zu erfassen.
%Vor%Laut der Antwort des Mobs ist dies eine der "cleveren, aber nicht unbedingt schlauen" Varianten. Wenn Sie den zusätzlichen Parameter ablehnen, können Sie stattdessen currying verwenden.
%Vor%Dies ist in keiner Weise effizienter, lesbarer oder wertvoller, aber es könnte interessant sein, etwas über die Technik dort zu wissen, wo sie wirklich nützlich ist.
Tags und Links perl
Siehe SO-Frage für eine detaillierte Antwort auf wie es funktioniert.
Meiner Erfahrung nach möchte ich interne Mitglieder in Erwartung einer zukünftigen Zeit, in der ich den Umfang der Klasse öffentlich machen möchte, öffentlich bekannt machen. Auf diese Weise kann ich das tun und alle zuvor markierten internen Methoden sind automatisch öffentlich.
Für mich lautet das: "Eine Methode, auf die jeder zugreifen kann, unabhängig von der Assembly, die in einer Klasse lebt, auf die nur über den Code in derselben Assembly zugegriffen werden kann."
Für mich bedeutet das: "Die Zugriffsdomäne von C ist auf diese Assembly beschränkt; die Zugriffsdomäne von M ist die uneingeschränkte Teilmenge der Zugriffsdomäne ihres Containers C ".
"öffentlich" bedeutet das für mich, weil das in der Spezifikation bedeutet, dass es bedeutet. Ich empfehle Ihnen, den Teil der Spezifikation zu lesen, der Bereiche für die Barrierefreiheit behandelt, wenn Sie Fragen oder Bedenken zu diesem Thema haben.
Zum Beispiel:
%Vor%Für mich lautet das " eine Methode, auf die jeder zugreifen kann, unabhängig von der Assembly, die in einer Klasse lebt, auf die nur über Code in derselben Assembly zugegriffen werden kann ".
Meine Erfahrung mit dem Compiler sagt mir, dass wenn ich so etwas mache und keine Warnung erhalte, es wahrscheinlich einen guten Grund dafür gibt.
Also, ich nehme an, entweder
(wenn 2, das ist kein Versuch, sich darüber zu beschweren - ich will nur verstehen)
Das %code% -Schlüsselwort beschränkt den Zugriff auf %code% auf nur Aufrufe, die innerhalb der Assembly vorgenommen wurden, in der sich %code% befindet.
%code% bedeutet nur, dass jeder auf das Mitglied zugreifen kann. %code% kennt oder kümmert sich nicht um Beschränkungen, die in der Klassenhierarchie höher platziert sind, und sollte es auch nicht.
Es ist "mit Absicht", mit anderen Worten. Wenn Sie %code% auf eine Methode setzen, geht der Compiler davon aus, dass Sie bereits wissen, dass Sie, wenn Sie der Klasse selbst weitere Einschränkungen auferlegen, wissen müssen, was Sie tun.
Der Gültigkeitsbereich der Klasse ist intern. Es scheint also keinen Sinn zu haben, öffentliche Eigenschaft zu haben, da nur die Klassen im Namensraum die Klasse sehen können, um die Eigenschaft zu sehen. Wenn du irgendwann beschlossen hast, die Klasse öffentlich zu machen, wäre es eine massive PIA, jedes Mitglied durchzugehen und seinen Umfang zu ändern.