Dies ist ein Fehler in Perl 6: X :: AdHoc anstelle von X :: TypeCheck :: Binding mit Subset-Parameter , erstmals im November 2015 gemeldet.
Während ich mit meinem Modul Perl 6 Chemisty :: Elements gespielt habe, bin ich auf Ausnahme Problem, das ich nicht erwartet habe.
Ich definiere einen Typ, ZInt
, der Zahlen auf die Ordnungszahlen beschränkt, die im periodischen Diagramm gefunden werden (was ich hier ein bisschen vorgetäuscht habe). Ich verwende diesen Typ dann, um einen Parameter auf eine Subroutine zu beschränken. Ich habe erwartet, dass ich eine Art X :: TypeCheck bekomme, aber ich bekomme X::AdHoc statt:
Zuerst bekomme ich die Warnung zweimal, was seltsam ist:
Z muss zwischen einer positiven ganzen Zahl von 1 bis 120 liegen. Get & lt; 156 & gt ;. in Block bei zint.p6 Zeile 5 Z muss zwischen einer positiven ganzen Zahl von 1 bis 120 liegen. Get & lt; 156 & gt ;. in Block bei zint.p6 Zeile 5 X :: AdHoc
Aber ich bekomme den X::AdHoc
-Typ, wenn die Leute lieber wüssten, dass es sich um einen Typfehler handelt.
Ich habe überprüft, was ohne die warn
passieren würde und habe X::AdHoc
wieder:
Also dachte ich, ich könnte meine eigene Ausnahme werfen:
%Vor%Aber ich bekomme eine Warnung:
Verwendung des nicht initialisierten Wertes vom Typ Any im Stringkontext Jeder von. ^ Name, .perl, .gist oder .say kann bei Bedarf undefinierte Dinge stringieren.
An diesem Punkt weiß ich nicht, was sich beschweren. Ich gehe davon aus, dass eine dieser Methoden etwas erwartet, das ich nicht liefere, aber ich sehe nichts über Parameter für new
oder throw
in den Dokumenten.
Wie erhalte ich den gewünschten Typ ohne die Warnung zusammen mit meinem benutzerdefinierten Text?
Werfen Sie die Ausnahme nicht oder warnen Sie mit einer Ausnahme. Stattdessen möchten Sie fehlschlagen:
%Vor%Ich glaube, das ist deine Absicht. Das Scheitern mit Ihrer eigenen Ausnahme ist auch in Ordnung, aber X :: TypeCheck hat einen Fehler darin. Es sollte entweder "Operation" erfordern oder einen angemessenen Standard wie für "erhalten" und "erwartet" bereitstellen.
%Vor% Sie könnten --ll-exception
übergeben und versuchen herauszufinden, wie genau Sie mit den Fehlern und Meldungen enden, die Sie bekommen haben, aber ich bin mir nicht sicher, wie hilfreich das sein wird.
Zur Warnung bezüglich der Verwendung eines nicht initialisierten Wertes: Sie müssen operation
ein benanntes Argument X::TypeCheck.new
angeben; Andere Argumente, die Sie angeben können, sind got
und expected
, cf core / Exception .pm .
Es ist jedoch eine schlechte Idee, von einer Untergruppen-Deklaration zu werfen, da jedes Smartmatch gegen diesen speziellen Typ nun explodiert. Eine etwas bessere Idee wäre .fail
die Ausnahme, aber das fühlt sich immer noch nicht richtig an: Nicht Mitglied eines Subset-Typs zu sein, ist keine Ausnahme.
Alternativ können Sie einen Mehrfachkandidaten angeben, der das Sterben ausführt:
%Vor% Es gibt immer noch Probleme, wenn Sie ein Argument wie "hello"
angeben, das bei der numerischen Konvertierung fehlschlägt, da %%
den Fehler auslöst, anstatt den Fehler weiterzuleiten, was als Fehler in der Rakudo-Kerneinstellung betrachtet werden könnte.
Sie können das über Dinge wie
umgehen %Vor%oder
%Vor%Die gesamte Interaktion der Überprüfung von Argumenttypen, Teilmengen oder Where-Klauseln, Fehlern und Ausnahmen kann etwas brüchig sein. Daher sollten Sie ein wenig experimentieren, bis Sie zu einer Semantik und einem Verhalten kommen, das Ihnen gefällt.
Ein anderer Ansatz wäre eine Nötigung von Cool
nach Int
mit einer separaten Bereichsprüfung:
In einer idealen Welt sollte es eine Möglichkeit geben, dies mit einer Zwangsbedingung wie ZInt(Cool)
auszudrücken.