Festlegen von Einstellungen für Optionen

8

Wie geben Sie explizit die gültigen Einstellungen für eine Option an? Nehmen Sie dieses Beispiel zum Beispiel

%Vor%

myFunc gibt den Wert der Option aus. Wenn wir myFunc[opt1 -> {1, 2}] auswerten, wird {1, 2} ausgegeben. Diese Funktion druckt grundsätzlich alles, was Sie auf opt1 eingestellt haben. Meine Frage ist, wie kann ich sicherstellen, dass meine Funktion nur eine bestimmte Anzahl von Werten für opt1 akzeptiert. Wir können mit etwas Einfachem wie String und Integer beginnen.

Um eine bessere Vorstellung von dem Verhalten zu bekommen, das wir mit den falschen Werten für opt1 erhalten würden, können wir uns ansehen, was passiert, wenn wir für PlotRange in der Funktion Plot .

Im Beispiel im Bild habe ich absichtlich den PlotRange -Optionen falsche Werte gegeben und mir eine Nachricht gegeben, die den richtigen Typ von Werten für diese speziellen Optionen angibt. Es scheint, dass PlotRange seinen Standardwert angenommen hat und somit das Objekt Graphics zurückgibt.

In dem einfachen Beispiel, das wir erhalten möchten, ist etwa:

%Vor%

Weiß jemand, wie man das erreicht?

    
jmlopez 05.07.2011, 19:28
quelle

1 Antwort

7

Eine einfache Lösung

Hier ist ein einfacher Weg:

%Vor%

Zum Beispiel:

%Vor%

Dies wird mit benutzerdefinierten Zuweisungsoperatoren allgemein gemacht

Wir können die Tatsache verwenden, dass OptionValue innerhalb einer Funktion mit einem einzelnen Argument arbeitet, das ein Optionsname ist, um die Langeweile der Fehlerprüfung herauszufiltern. Dies ist möglich durch Verwendung von mma Meta-Programmiermöglichkeiten. Hier ist der Code für einen benutzerdefinierten Zuweisungsoperator:

%Vor%

Was es tut, ist, eine Funktionsdefinition als Regel f_[args___]:>body_ zu nehmen, und auch die Spezifikationen für die Einstellungen der zulässigen Optionen und die Aktionen, die bei Erkennung eines Fehlers in einer der übergebenen Optionen ausgeführt werden sollen. Wir injizieren dann den Fehlerprüfcode ( Scan ), bevor der Body ausgeführt wird. Sobald die erste Option mit unangemessener Einstellung gefunden wird, wird das Fehler-Flag auf True gesetzt, und welcher Code auch immer im Fail:>code_ -Teil der Spezifikationen für diese Option angegeben wird. Das Optionsspezifikationsmuster (_ -> {_, Fail :> _}) sollte (optname_ -> {optpattern_, Fail :> onerror_}) lesen, wobei optname ein Optionsname ist, optpattern ein Muster, das der Optionswert übereinstimmen muss, und onerror ist ein beliebiger Code, der ausgeführt wird, wenn ein Fehler festgestellt wird. Beachten Sie, dass wir RuleDelayed in Fail:>onerror_ verwenden, um eine vorzeitige Auswertung dieses Codes zu verhindern. Hinweis b.t.w. dass der OptionSpecs -Wrapper nur zur besseren Lesbarkeit hinzugefügt wurde - es ist ein völlig leeres Symbol, an das keine Regeln angehängt sind.

Hier ist ein Beispiel für eine Funktion, die mit diesem benutzerdefinierten Zuweisungsoperator definiert wurde:

%Vor%

Hier sind Beispiele für die Verwendung:

%Vor%

Optionsprüfungen zu bereits definierten Funktionen automatisch hinzufügen

Sie könnten auch an einem Paket interessiert sein, das ich geschrieben habe, um die übergebenen Optionen zu testen: CheckOptions , verfügbar hier . Das Paket wird mit einem Notebook geliefert, das seine Verwendung veranschaulicht. Es analysiert die Definitionen Ihrer Funktion und erstellt zusätzliche Definitionen, um die Optionen zu überprüfen. Der aktuelle Nachteil (abgesehen von der Generierung neuer Definitionen, die möglicherweise nicht immer angemessen sind) ist, dass es nur die ältere Möglichkeit zur Definition von Optionen durch OptionQ Prädikat abdeckt (Ich habe es noch nicht aktualisiert, um OptionValue - OptionsPattern abzudecken Teil des beiliegenden Notizbuchs, um zu illustrieren, wie es funktioniert:

Betrachten Sie eine Modellfunktion:

%Vor%

Angenommen, wir möchten eine Fehlermeldung ausgeben, wenn eine Option FontSize an unsere Funktion übergeben wird:

%Vor%

Wir fügen die Option - Prüfdefinitionen hinzu:

%Vor%

Wie Sie sehen, werden nach dem Aufruf von AddOptionsCheck neue Definitionen generiert. Er übernimmt den Funktionsnamen, die Testfunktion und die Funktion, die bei einem Fehler ausgeführt werden soll. Die Testfunktion akzeptiert den Namen der Hauptfunktion, Optionen, die an sie übergeben wurden (in Hold eingeschlossen), und Argumente, die nicht an Optionen übergeben wurden (auch in Hold eingeschlossen). Aus den generierten Definitionen können Sie sehen, was funktioniert.

Wir prüfen nun verschiedene Eingaben:

%Vor%

Bitte beachten Sie, dass die Testfunktion auf eine beliebige Bedingung testen kann, die Funktionsnamen, übergebene Argumente und übergebene Optionen enthält. Es gibt ein weiteres Paket von mir, PackageOptionChecks , das auf derselben Seite verfügbar ist und eine einfachere Syntax hat, um speziell r.h.s. von Optionen, und kann auch auf das gesamte Paket angewendet werden. Ein praktisches Anwendungsbeispiel ist ein weiteres Paket, PackageSymbolsDependencies , dessen Funktionen durch PackageOptionChecks "geschützt" sind. Außerdem kann PackageOptionChecks auch auf Funktionen in Global' context angewendet werden, es ist nicht notwendig, ein Paket zu haben.

Eine weitere Einschränkung der aktuellen Implementierung besteht darin, dass die Funktion nicht unbewertet zurückgegeben werden kann. Bitte lesen Sie eine ausführlichere Diskussion in dem Notebook, das dem Paket beiliegt. Wenn es genug Interesse daran gibt, werde ich in Betracht ziehen, das Paket zu aktualisieren, um einige der erwähnten Einschränkungen zu beseitigen.

    
Leonid Shifrin 05.07.2011, 19:54
quelle

Tags und Links