Gibt es eine Möglichkeit, ein Symbol sicher neu zu deklarieren?

9

Ich experimentiere oft in der REPL und ich werde etwas sagen wie:

subset Bar of Int where * %% 57;

Dann spiele ich Barein bisschen mit der Überprüfung der -ness für Dinge herum .

Alles ist glücklich, bis mir klar wird, dass ich die Definition von ändern möchte Bar.

Wenn ich nur neu definiere Bar, bekomme ich eine Redeclaration of symbolAusnahme.

Ich habe versucht, dies zu verwenden MONKEY-TYPINGund zu augmentmögen:

use MONKEY-TYPING;
augment subset Bar of Int where * %% 37;

Aber das brachte mir den gleichen Fehler ein.

Warum will ich das? So kann ich meine Teilmengen- (oder Klassen- oder andere Symbol-) Definitionen durchlaufen, während ich die Tests, die ich bereits eingegeben habe und die sich in meinem Verlauf befinden, wiederverwenden kann.

daotoad
quelle

Antworten:

3

Ich denke, die REPL leistet einen Teil ihrer Magie, indem sie EVALjede neue Eingabe in einen neuen verschachtelten lexikalischen Bereich einfügt. Wenn Sie also Dinge mit deklarieren my, können Sie sie mit später eingegebenen Deklarationen beschatten:

my subset Bar of Int where * %% 57;
sub take-Bar(Bar $n) { say "$n is Bar" }
take-Bar 57;

my subset Bar of Int where * %% 42;
sub take-Bar(Bar $n) { say "$n is Bar" }
take-Bar 42;

Wenn Sie weglassen my, werden for subsetund classDeklarationen ourverwendet, und da ourwird tatsächlich my+ das Symbol zum beiliegenden Paket hinzugefügt ...; Wenn Sie das Symbol aus dem Paket löschen, können Sie es später erneut schattieren:

subset Bar of Int where * %% 57;
GLOBAL::<Bar>:delete;
subset Bar of Int where * %% 42;
42 ~~ Bar;

HINWEIS: Diese Ergebnisse stammen nur aus meinen Experimenten in der REPL. Ich bin mir nicht sicher, ob es andere unbekannte Nebenwirkungen gibt.

Cowbaymoo
quelle
8

Das REPLhat seine Mängel. Es ist eine aufwändige Konstruktion von EVALAussagen, die versuchen, zusammenzuarbeiten. Manchmal klappt das nicht.

Ich denke, das Beste, was wir tun können, ist, einen REPL-Befehl einzuführen, der alles vergessen lässt, was er zuvor getan hat. Patches willkommen! :-)

Elizabeth Mattijsen
quelle
Wenn ich das richtig verstehe, war ich auf dem richtigen Weg use MONKEY-TYPINGund augmentaber sie funktionieren in der REPL (noch?) Nicht richtig, weil sie viel Magie und Entenband benötigt.
Daotoad
1
AFAIK, Sie können Augment nur verwenden, um einer Klasse etwas hinzuzufügen . Sie versuchen, eine Teilmenge zu ersetzen .
Elizabeth Mattijsen
1
@daotoad Zum Ersetzen können Sie verwenden supersede, aber ich glaube, dass dies derzeit nicht implementiert ist.
user0721090601
1
Supersede ist noch nicht implementiert, aber das würde sowieso nur auf installierter Modulebene funktionieren. Die Ersetzungsfunktion sollte es einem Modul ermöglichen, anzuzeigen, dass es anstelle eines anderen Moduls / einer anderen Version geladen werden soll. Es ist daher ein Hinweis auf das CompUnitRepo, wenn Sie gefragt werden, ob es ein bestimmtes Modul bereitstellen kann.
Elizabeth Mattijsen