Skip to content

Paketqualifizierte Namen. Unterschiede (falls vorhanden) zwischen Paket:: vs &Paket::var?

Lösung:

Unterschiede sind mir nicht bekannt, aber Foo::Bar::<&zape> kann auch modifiziert werden, um zu verwenden {} Anstatt von <>, die dann mit etwas anderem als Literalen verwendet werden kann, wie folgt:

my $name="&zape";
Foo::Bar::{$name}()

oder

my $name="zape";
&Foo::Bar::{$name}()

Es gibt keine Unterschiede zwischen Package::<&var> und &Package::var.

package Foo { our $var = "Bar" };
say $Foo::var === Foo::<$var>; # OUTPUT: «True␤» 

Dito für Subs (natürlich):

package Foo { our &zape = { "Bar" } };
say &Foo::zape === Foo::<&zape>;# OUTPUT: «True␤»

Was die Dokumentation (etwas verwirrend) sagen will, ist, dass auf Variablen im Paketbereich nur zugegriffen werden kann, wenn sie mit our deklariert werden. Es gibt zwei zapes, einer von ihnen hat einen lexikalischen Geltungsbereich (subs erhalten standardmäßig einen lexikalischen Geltungsbereich), sodass Sie nicht auf diesen zugreifen können. Ich habe dieses Problem im Doc-Repo angesprochen und werde versuchen, es so schnell wie möglich zu beheben.

JJ und Moritz haben nützliche Antworten geliefert.

Diese Antwort ist eine ganz andere Wachskugel. Ich habe in den letzten Tagen mehrere Antworten auf Ihre Frage geschrieben und verschrottet. Keine war sehr nützlich. Ich bin mir auch nicht sicher, ob dies der Fall ist, aber ich habe beschlossen, dass ich endlich eine erste Version von etwas habe, das es wert ist, veröffentlicht zu werden, unabhängig von seiner aktuellen Nützlichkeit.

In diesem ersten Teil besteht meine Antwort nur aus einer Reihe von Beobachtungen und Fragen. Ich hoffe auch, eine hinzufügen zu können Erläuterung meiner Beobachtungen basierend auf dem, was ich aus dem Spelunking des Compiler-Codes lese, um verstehen was wir sehen. (Im Moment habe ich nur den Beginn dieses Prozesses als zweite Hälfte dieser Antwort aufgeschrieben.)

Unterschiede (falls vorhanden) zwischen Package::<&var> vs &Package::var?

Sie haben eine grundlegend andere Syntax. Sie sind nicht vollständig austauschbar, wo Sie sie schreiben können. Sie führen zu unterschiedlichen Bewertungen. Ihr Ergebnis kann verschiedene Dinge sein.

Lassen Sie uns viele Variationen durchgehen, die die Unterschiede herausarbeiten.

say Package::<&var>; # compile-time error: Undeclared name: Package

Also vergiss die ::<...> für einen Moment ein bisschen. P6 schaut sich das an Package Bit und verlangt, dass es ein bereits deklarierter Name ist. Das scheint einfach genug.

say &Package::var; # (Any)

Ganz ein Unterschied! Aus irgendeinem Grund hat P6 für diese zweite Syntax kein Problem mit diesen beiden willkürlichen Namen (Package und var) nicht deklariert. Wer weiß was es mit dem macht &. Und warum ist es (Any) und nicht (Callable) oder Nil?

Versuchen wir, diese Dinge zu deklarieren. Zuerst:

my Package::<&var> = { 42 } # compile-time error: Type 'Package' is not declared

OK. Aber wenn wir erklären Package die Dinge verbessern sich nicht wirklich:

package Package {}
my Package::<&var> = { 42 } # compile-time error: Malformed my

OK, fang wieder mit einer sauberen Schiefertafel an, ohne die package Erklärung. Was ist mit der anderen Syntax?:

my &Package::var = { 42 }

Yay. P6 akzeptiert diesen Code. In den nächsten Zeilen gehen wir nun von der obigen Deklaration aus. Wie wäre es mit:

say &Package::var(); # 42

o/ Können wir also die andere Syntax verwenden?:

say Package::<&var>(); # compile-time error: Undeclared name: Package

Nö. Es scheint wie die my nicht deklariert Package mit einem &var drin. Vielleicht hat es a . deklariert &Package::var, bei dem die :: ist nur zufällig ein Teil des Namens, aber es geht nicht um Pakete? P6 unterstützt eine Reihe von "Pseudo"-Paketen. Einer von ihnen ist LEXICAL:

say LEXICAL::; # PseudoStash.new(... &Package::var => (Callable) ... 

Bingo. Oder ist es?

say LEXICAL::<&Package::var>(); # Cannot invoke this object
                                # (REPR: Uninstantiable; Callable)

Was ist mit unserem passiert { 42 }?

Hmm. Beginnen wir bei Null und schaffen wir &Package::var ganz anders:

package Package { our sub var { 99 } }
say &Package::var();   # 99
say Package::<&var>(); # 99

Beeindruckend. Nehmen wir nun die obigen Zeilen an und versuchen Sie, mehr hinzuzufügen:

my Package::<&var> = { 42 } # Compile-time error: Malformed my

Das war angesichts unseres vorherigen Versuchs oben zu erwarten. Wie wäre es mit:

my &Package::var = { 42 }   # Cannot modify an immutable Sub (&var)

Macht jetzt alles Sinn? 😉

Den Compilercode buchstabieren, die Grammatik überprüfen

1 Ich habe lange versucht, herauszufinden, was der Deal ist Ja wirklich ist, bevor Sie sich den Quellcode des Rakudo-Compilers ansehen. Dies ist eine Fußnote zu meinem ersten Compiler-Spelunking. Ich hoffe, dass ich es morgen fortsetzen kann und diese Antwort dieses Wochenende in eine Antwort umwandeln kann.

Die gute Nachricht ist, dass es nur P6-Code ist – der größte Teil von Rakudo ist in P6 geschrieben.

Die schlechte Nachricht ist, zu wissen, wo man suchen muss. Sie könnten das sehen doc Verzeichnis und dann die Compilerübersicht. Aber dann werden Sie feststellen, dass das Übersichtsdokument seit 2010 kaum angerührt wurde! Mach dir keine Mühe. Vielleicht helfen dir die "internen" Beiträge von Andrew Shitov bei der Orientierung? Weiter geht's...

In diesem Fall interessiert mich, die genaue Natur der Package::<&var> und &Package::var Formen der Syntax. Wenn ich "Syntax" in das Repository-Suchfeld von GH eintippe, ist die zweite aufgeführte Datei die Perl 6-Grammatik. Bingo.

Jetzt kommt die hässliche Nachricht. Die Perl 6 Grammatikdatei ist 6K LOC und sieht super einschüchternd aus. Aber ich finde, es macht alles Sinn, wenn ich cool bleibe.

Als nächstes frage ich mich, wonach ich auf der Seite suchen soll. :: Netze über 600 Spiele. Hmm. ::< ist nur 1, aber es ist in einer Fehlermeldung. Aber worin? In token morename. Wenn ich mir das ansehe, kann ich sehen, dass es wahrscheinlich ist nicht relevant. Aber die '::' In der Nähe des Anfangs des Tokens befindet sich nur das Ticket. Suche auf der Seite nach '::' ergibt 10 Treffer. Die ersten 4 (vom Dateianfang) sind weitere Fehlermeldungen. Die nächsten beiden sind oben morename Zeichen. Noch 4 Spiele.

Der nächste erscheint ein Viertel der Strecke token term:sym<name>. Ein Name". .oO ( Undeclared name: Package Vielleicht ist das also relevant? )

Nächste, token typename. Ein "Typname". .oO ( Type 'Package' is not declared Also ist das vielleicht auch relevant? )

token methodop. Definitiv nicht relevant.

Schließlich token infix:sym<?? !!>. Nö.

Click to rate this post!
[Total: 0 Average: 0]



Anderer Beitrag

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.