(* Content-type: application/mathematica *) (*** Wolfram Notebook File ***) (* http://www.wolfram.com/nb *) (* CreatedBy='Mathematica 6.0' *) (*CacheID: 234*) (* Internal cache information: NotebookFileLineBreakTest NotebookFileLineBreakTest NotebookDataPosition[ 145, 7] NotebookDataLength[ 74743, 2235] NotebookOptionsPosition[ 67467, 1988] NotebookOutlinePosition[ 68088, 2013] CellTagsIndexPosition[ 68002, 2008] WindowFrame->Normal ContainsDynamic->True *) (* Beginning of Notebook Content *) Notebook[{ Cell[CellGroupData[{ Cell[TextData[{ "Protecting functions from inappropriate options with \t\t\t", StyleBox["CheckOptions`", FontWeight->"Bold", FontSlant->"Italic"] }], "Subtitle", CellChangeTimes->{{3.441615231458573*^9, 3.4416152651069565`*^9}, { 3.4416153789406414`*^9, 3.441615402594654*^9}, {3.4418125279535294`*^9, 3.4418125311781664`*^9}, {3.4418127693005695`*^9, 3.4418127744279423`*^9}}],\ Cell[CellGroupData[{ Cell["\<\ Author: \t\t\tLeonid B. Shifrin \t\t\t \t\t\tleonid@mathprogramming-intro.org, \t\t\tshifrinl@hotmail.com\ \>", "Subsection", CellChangeTimes->{{3.4416153043333616`*^9, 3.441615358240877*^9}, { 3.4416175573931026`*^9, 3.441617572254472*^9}}, FontWeight->"Plain"], Cell["Package version 1.0 - January 2009", "Subsubsection", CellChangeTimes->{{3.441703718150744*^9, 3.441703747372763*^9}}, FontWeight->"Plain"], Cell[TextData[{ StyleBox["Mathematica", FontSlant->"Italic"], " version 5.0+ " }], "Subsubsection", CellChangeTimes->{{3.4417037513885374`*^9, 3.4417037599107924`*^9}, { 3.441703818074427*^9, 3.4417038219600143`*^9}, 3.4418064057502337`*^9}, FontWeight->"Plain"] }, Open ]], Cell[CellGroupData[{ Cell["Introduction", "Section", CellChangeTimes->{{3.441809151728757*^9, 3.4418091558847327`*^9}}, FontWeight->"Plain"], Cell[TextData[{ "The package allows one to add new definitions to option - receiving \ functions. These new definitions will be tried before the old ones and can \ check passed options for validity, testing both option name and its r.h.s. \ The tests are specified by the user of the package. In case of option \ considered \"inappropriate\", the code (function) specified by the user will \ be executed.\n\nThe functionality of this package is supposed to complement \ the standard option-filtering done with the help of \ FilterOptions/FilterRules. At present, the main pre - requisite for this to \ work is that all option - taking functions to be protected have in their \ signature (s) options declared as ", StyleBox["opts___?OptionQ", FontWeight->"Bold", FontSlant->"Italic"], " (name < opts > can be arbitrary). The constructs ", StyleBox["OptionPattern", FontWeight->"Bold", FontSlant->"Italic"], " - ", StyleBox["OptionValue", FontWeight->"Bold", FontSlant->"Italic"], ", introduced in v.6.0, are not yet covered. The work to incorporate them is \ underway.\n \n The package can be used as a bulletproofing/debugging tool \ when dealing with functions written for earlier (than 6.0) versions of ", StyleBox["Mathematica", FontSlant->"Italic"], " (where still ", StyleBox["opts___?OptionQ", FontWeight->"Bold", FontSlant->"Italic"], " pattern was used), or if one still prefers to use this pattern in newer \ versions of ", StyleBox["Mathematica. ", FontSlant->"Italic"], "The present package works on the level of individual functions. I wrote \ another package , that builds on the present one and \ automates such \"protection\" more, elevating it to the level of entire \ packages/contexts (however, also in that package control on the level of \ individual functions is possible)." }], "Text", CellChangeTimes->{{3.4418091665901265`*^9, 3.441809344145438*^9}, { 3.441809378905421*^9, 3.441809423950192*^9}, 3.4418094616343794`*^9, { 3.4418094995488977`*^9, 3.4418096364056883`*^9}, {3.4418096726678305`*^9, 3.441809707628101*^9}}] }, Closed]], Cell[CellGroupData[{ Cell["Illustration", "Section", CellChangeTimes->{{3.441809122286421*^9, 3.4418091317500286`*^9}}, FontWeight->"Plain"], Cell[CellGroupData[{ Cell["Preliminaries", "Subsection", CellChangeTimes->{{3.4418087044556093`*^9, 3.441808708231038*^9}}, FontWeight->"Plain"], Cell["\<\ Letting Mathematica know the location of the package (use the directory where \ you have placed it on your machine)\ \>", "Text", CellChangeTimes->{{3.4409305683520465`*^9, 3.440930606076291*^9}, 3.4418128322110305`*^9}], Cell[BoxData[ RowBox[{ RowBox[{"AppendTo", "[", RowBox[{ "$Path", ",", "\"\\""}], "]"}], ";"}]], "Input", CellChangeTimes->{{3.4306365337101617`*^9, 3.4306365531481123`*^9}, { 3.440922253686144*^9, 3.440922255188304*^9}}, FontWeight->"Plain"], Cell["Load the package", "Text", CellChangeTimes->{{3.4409306137773647`*^9, 3.4409306166414833`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"Needs", "[", "\"\\"", "]"}], ";"}]], "Input", CellChangeTimes->{{3.440922279923872*^9, 3.44092228763496*^9}}], Cell["The interface :", "Text", CellChangeTimes->{{3.4409306342768416`*^9, 3.440930636990744*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"?", "CheckOptions`*"}]], "Input", CellChangeTimes->{3.4409222949354577`*^9}], Cell[BoxData[ DynamicModuleBox[{Typeset`open$$ = True}, PaneSelectorBox[{False-> RowBox[{ OpenerBox[Dynamic[Typeset`open$$], ImageSize->Small], StyleBox["CheckOptions`", "InfoHeading"]}], True->GridBox[{ { RowBox[{ OpenerBox[Dynamic[Typeset`open$$], ImageSize->Small], StyleBox["CheckOptions`", "InfoHeading"]}]}, {GridBox[{ { ButtonBox["AddOptionsCheck", BaseStyle->"InformationLink", ButtonData:>{ "Info3441785379-5130581", "CheckOptions`AddOptionsCheck"}, ButtonNote->"CheckOptions`"], ButtonBox["RemoveAllOptionsChecks", BaseStyle->"InformationLink", ButtonData:>{ "Info3441785379-5130581", "CheckOptions`RemoveAllOptionsChecks"}, ButtonNote->"CheckOptions`"]}, { ButtonBox["OptionIsChecked", BaseStyle->"InformationLink", ButtonData:>{ "Info3441785379-5130581", "CheckOptions`OptionIsChecked"}, ButtonNote->"CheckOptions`"], ButtonBox["RemoveOptionsCheck", BaseStyle->"InformationLink", ButtonData:>{ "Info3441785379-5130581", "CheckOptions`RemoveOptionsCheck"}, ButtonNote->"CheckOptions`"]} }, DefaultBaseStyle->"InfoGrid", GridBoxItemSize->{"Columns" -> {{ Scaled[0.475]}}}]} }, GridBoxAlignment->{"Columns" -> {{Left}}, "Rows" -> {{Baseline}}}]}, Dynamic[Typeset`open$$], ImageSize->Automatic]]], "Print", "InfoCell", CellChangeTimes->{3.441814179918939*^9}] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell["Adding option protection to a function", "Subsection", CellChangeTimes->{{3.441808734468766*^9, 3.4418087494603233`*^9}}, FontWeight->"Plain"], Cell["Consider a model function :", "Text", CellChangeTimes->{{3.4409307803969517`*^9, 3.4409307884885874`*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"ClearAll", "[", "f", "]"}], ";"}], "\n", RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", " ", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], ":=", " ", RowBox[{"x", "^", "2"}]}], ";"}], "\n", RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", " ", "y_", ",", " ", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], " ", ":=", " ", RowBox[{"x", " ", "+", " ", "y"}]}], ";"}], "\n", RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", " ", "y_", ",", " ", "z_"}], "]"}], " ", ":=", " ", RowBox[{"x", "*", "y", "*", "z"}]}], ";"}]}], "Input", CellChangeTimes->{{3.44092577214544*^9, 3.4409257743385935`*^9}, { 3.440928326578534*^9, 3.4409283302137613`*^9}, {3.4409348747543488`*^9, 3.440934895694459*^9}}, FontWeight->"Plain"], Cell["\<\ Suppose we want to return an error message when an option FontSize is passed \ to our function :\ \>", "Text", CellChangeTimes->{{3.4409226098883376`*^9, 3.4409226120614624`*^9}, { 3.4409306501396513`*^9, 3.440930666062547*^9}, {3.4409307556012974`*^9, 3.440930793035125*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{ RowBox[{"f", "::", "badopt"}], "=", "\"\\""}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"test", "[", RowBox[{"f", ",", "heldopts_Hold", ",", "heldArgs_Hold"}], "]"}], ":=", RowBox[{ RowBox[{"(", RowBox[{"FontSize", "/.", RowBox[{"Flatten", "[", RowBox[{"List", "@@", "heldopts"}], "]"}]}], ")"}], "=!=", "FontSize"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"rhsF", "[", RowBox[{"f", ",", "__"}], "]"}], ":=", RowBox[{"(", RowBox[{ RowBox[{"Message", "[", RowBox[{"f", "::", "badopt"}], "]"}], ";", "$Failed"}], ")"}]}], ";"}]}], "Input", CellChangeTimes->{{3.440922536072195*^9, 3.440922575468845*^9}, { 3.440922616668086*^9, 3.4409227660428767`*^9}, {3.440923764929205*^9, 3.4409237672425313`*^9}, {3.440930747609806*^9, 3.440930753498274*^9}, { 3.4409352430439234`*^9, 3.440935269652184*^9}}], Cell["We add the option - checking definitions :", "Text", CellChangeTimes->{{3.4409308088678913`*^9, 3.44093082975793*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test", ",", "rhsF"}], "]"}]], "Input", CellChangeTimes->{{3.440928284928645*^9, 3.440928290566752*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}]}], "}"}]], "Output", CellChangeTimes->{3.4418082179760866`*^9, 3.441814184896096*^9}] }, Open ]], Cell["We now check on various inputs :", "Text", CellChangeTimes->{{3.4409249651450305`*^9, 3.440924984592995*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", "3", "]"}]], "Input", CellChangeTimes->{{3.4409241827800446`*^9, 3.4409241837013693`*^9}}], Cell[BoxData["9"], "Output", CellChangeTimes->{3.441808220069096*^9, 3.4418142042639456`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"3", ",", RowBox[{"FontWeight", "\[Rule]", "Bold"}]}], "]"}]], "Input", CellChangeTimes->{{3.440924199263747*^9, 3.440924204240904*^9}}], Cell[BoxData["9"], "Output", CellChangeTimes->{3.4418082209603777`*^9, 3.4418142050851264`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"3", ",", RowBox[{"FontWeight", "\[Rule]", "Bold"}], ",", RowBox[{"FontSize", "\[Rule]", "5"}]}], "]"}]], "Input", CellChangeTimes->{{3.440924126248757*^9, 3.4409241351816015`*^9}, { 3.4409242099991837`*^9, 3.440924240963709*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"f", "::", "\<\"badopt\"\>"}], RowBox[{":", " "}], "\<\"Inappropriate option\"\>"}]], "Message", CellChangeTimes->{3.441808234209429*^9, 3.44181420752864*^9}], Cell[BoxData["$Failed"], "Output", CellChangeTimes->{3.441808234229458*^9, 3.441814207548669*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"a", ",", "b"}], "]"}]], "Input", CellChangeTimes->{{3.4409241827800446`*^9, 3.4409241837013693`*^9}, { 3.440924242966589*^9, 3.44092424385787*^9}}], Cell[BoxData[ RowBox[{"a", "+", "b"}]], "Output", CellChangeTimes->{3.4418082489506254`*^9, 3.441814209110915*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"a", ",", "b", ",", RowBox[{"FontWeight", "\[Rule]", "Bold"}]}], "]"}]], "Input", CellChangeTimes->{{3.440924199263747*^9, 3.440924204240904*^9}, { 3.440924246932291*^9, 3.4409242479938173`*^9}}], Cell[BoxData[ RowBox[{"a", "+", "b"}]], "Output", CellChangeTimes->{3.441808253256818*^9, 3.4418142098920383`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"a", ",", "b", ",", RowBox[{"FontWeight", "\[Rule]", "Bold"}], ",", RowBox[{"FontSize", "\[Rule]", "5"}]}], "]"}]], "Input", CellChangeTimes->{{3.440924126248757*^9, 3.4409241351816015`*^9}, { 3.4409242099991837`*^9, 3.4409242110607104`*^9}, {3.4409242501068563`*^9, 3.4409242512484975`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"f", "::", "\<\"badopt\"\>"}], RowBox[{":", " "}], "\<\"Inappropriate option\"\>"}]], "Message", CellChangeTimes->{3.4418082545086174`*^9, 3.4418142113240976`*^9}], Cell[BoxData["$Failed"], "Output", CellChangeTimes->{3.441808254538661*^9, 3.4418142113741693`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"OptionIsChecked", "[", RowBox[{"f", ",", "test"}], "]"}]], "Input", CellChangeTimes->{{3.440946910310629*^9, 3.4409469381706896`*^9}}], Cell[BoxData["True"], "Output", CellChangeTimes->{3.4418082571323905`*^9, 3.4418142145587487`*^9}] }, Open ]], Cell["\<\ By the way, our test for the presence of FontSize option contains a \ bug : \ \>", "Text", CellChangeTimes->{{3.4409351387339325`*^9, 3.4409352037073603`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"a", ",", "b", ",", RowBox[{"FontWeight", "\[Rule]", "Bold"}], ",", RowBox[{"FontSize", "\[Rule]", "FontSize"}]}], "]"}]], "Input", CellChangeTimes->{{3.4409351592233953`*^9, 3.4409351619272833`*^9}}], Cell[BoxData[ RowBox[{"a", "+", "b"}]], "Output", CellChangeTimes->{3.4418082585544353`*^9, 3.44181422239001*^9}] }, Open ]], Cell["\<\ Note that one particular bit of normally present functionality the package \ fails to provide: if some of the options passed are invalid, we can execute \ arbitrary function but we can not return the original function unevaluated \ (this is what normally happens for system functions or those (properly) coded \ in packages). Thus, the only decent alternative we have here is to issue an \ error message and return (or Throw, if appropriate) $Failed. Note also that the present functionality is not the same as one provided by \ FilterOptions (package,v.5.2 or earlier) or FilterRules (system,v.6.0+), \ since it allows one to analyze individual options and react on wrong inputs \ (typically on the rhs of the option) before the main function's code has been \ executed, rather than just filtering those invalid options out. Also, its \ role is different - it automates the process of adding new error-checking \ definitions and allows to separate those from the main code.\ \>", "Text", CellChangeTimes->{{3.4409308613633757`*^9, 3.44093106225224*^9}, { 3.4409356090301857`*^9, 3.4409358497062607`*^9}, {3.440935893829707*^9, 3.440935906017232*^9}}] }, Closed]], Cell[CellGroupData[{ Cell["Adding the same tests more than once", "Subsection", CellChangeTimes->{{3.441808896341528*^9, 3.4418089064160147`*^9}}, FontWeight->"Plain"], Cell["\<\ The definitions involving < test > are added only once. In this case, we try \ to add them again and nothing happens :\ \>", "Text", CellChangeTimes->{{3.44092429552216*^9, 3.44092432231068*^9}, { 3.4409249974214416`*^9, 3.4409250185317965`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test", ",", "rhsF"}], "]"}]], "Input"], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}]}], "}"}]], "Output", CellChangeTimes->{3.4418082621295757`*^9, 3.4418143468389587`*^9}] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell["Updating tests for changes in function's definitions", "Subsection", CellChangeTimes->{{3.4418089325736275`*^9, 3.4418089640989585`*^9}}, FontWeight->"Plain"], Cell["We now add another definition for < f > :", "Text", CellChangeTimes->{{3.440924327858658*^9, 3.440924337512539*^9}}], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], ":=", RowBox[{ RowBox[{"(", RowBox[{"x", "+", "y"}], ")"}], RowBox[{"(", RowBox[{"z", "-", "t"}], ")"}]}]}], ";"}]], "Input", CellChangeTimes->{{3.4409243407471905`*^9, 3.440924402956643*^9}}], Cell["\<\ In this case, Mathematica re - ordered the rules according to more general \ rules (as it understands it) go after more specific ones, so our new \ definition appears last in the list :\ \>", "Text", CellChangeTimes->{{3.4409244054802723`*^9, 3.440924496290851*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"DownValues", "[", "f", "]"}]], "Input", CellChangeTimes->{{3.4409243407471905`*^9, 3.440924402956643*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{ RowBox[{"(", RowBox[{"x", "+", "y"}], ")"}], " ", RowBox[{"(", RowBox[{"z", "-", "t"}], ")"}]}]}]}], "}"}]], "Output", CellChangeTimes->{3.4418082661253214`*^9, 3.4418143538590527`*^9}] }, Open ]], Cell["We now add a new option check for it :", "Text", CellChangeTimes->{{3.4409245029904847`*^9, 3.44092451333536*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test", ",", "rhsF"}], "]"}]], "Input"], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{ RowBox[{"(", RowBox[{"x", "+", "y"}], ")"}], " ", RowBox[{"(", RowBox[{"z", "-", "t"}], ")"}]}]}]}], "}"}]], "Output", CellChangeTimes->{3.4418082684286337`*^9, 3.441814355811861*^9}] }, Open ]], Cell["\<\ We see that the new checking definition has indeed been added. Any further \ attempt to add checking definitions based on the same < test > function will \ fail :\ \>", "Text", CellChangeTimes->{{3.440924548966595*^9, 3.440924596885499*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test", ",", "rhsF"}], "]"}]], "Input"], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{ RowBox[{"(", RowBox[{"x", "+", "y"}], ")"}], " ", RowBox[{"(", RowBox[{"z", "-", "t"}], ")"}]}]}]}], "}"}]], "Output", CellChangeTimes->{3.441808270691888*^9, 3.4418143634929056`*^9}] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell["The case of several different test functions", "Subsection", CellChangeTimes->{{3.44180884640973*^9, 3.441808863824771*^9}}, FontWeight->"Plain"], Cell["\<\ But we can add checks based on different checking functions. Here we will add \ checks based on checking function < test1 > (undefined so far), and with the \ r.h.s function rhsF2 (also undefined) :\ \>", "Text", CellChangeTimes->{{3.4409246235538464`*^9, 3.4409246925330334`*^9}, { 3.441814378394333*^9, 3.441814381308523*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test1", ",", "rhsF2"}], "]"}]], "Input", CellChangeTimes->{{3.4409247059723587`*^9, 3.4409247073443313`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test1", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF2", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test1", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF2", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test1", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF2", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"} ]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{ RowBox[{"(", RowBox[{"x", "+", "y"}], ")"}], " ", RowBox[{"(", RowBox[{"z", "-", "t"}], ")"}]}]}]}], "}"}]], "Output", CellChangeTimes->{3.441808275789218*^9, 3.4418143834916625`*^9}] }, Open ]], Cell["The checks have been added. ", "Text", CellChangeTimes->{{3.440924738779533*^9, 3.4409247695938416`*^9}, { 3.44180899287033*^9, 3.4418089949433107`*^9}, {3.4418143974116783`*^9, 3.4418143981928015`*^9}}] }, Closed]], Cell[CellGroupData[{ Cell["Removing checking definitions", "Subsection", CellChangeTimes->{{3.441808997737328*^9, 3.4418090086530237`*^9}}, FontWeight->"Plain"], Cell["\<\ We can now remove, for example, checking definitions based on < test > :\ \>", "Text", CellChangeTimes->{{3.440924738779533*^9, 3.4409247695938416`*^9}, { 3.44180899287033*^9, 3.4418089949433107`*^9}, 3.4418144074260783`*^9}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"RemoveOptionsCheck", "[", RowBox[{"f", ",", "test"}], "]"}]], "Input", CellChangeTimes->{{3.4409247907843122`*^9, 3.4409248167316227`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test1", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF2", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test1", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF2", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test1", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF2", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"} ]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{ RowBox[{"(", RowBox[{"x", "+", "y"}], ")"}], " ", RowBox[{"(", RowBox[{"z", "-", "t"}], ")"}]}]}]}], "}"}]], "Output", CellChangeTimes->{3.441808280556072*^9, 3.4418144092687283`*^9}] }, Open ]], Cell["And then, those we added last :", "Text", CellChangeTimes->{{3.4409248203568354`*^9, 3.440924833766117*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"RemoveOptionsCheck", "[", RowBox[{"f", ",", "test1"}], "]"}]], "Input", CellChangeTimes->{3.4409248457433395`*^9}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{ RowBox[{"(", RowBox[{"x", "+", "y"}], ")"}], " ", RowBox[{"(", RowBox[{"z", "-", "t"}], ")"}]}]}]}], "}"}]], "Output", CellChangeTimes->{3.441808282699154*^9, 3.4418144128638973`*^9}] }, Open ]], Cell["\<\ Alternatively, we may remove all added definitions at once, with \ RemoveAllOptionsChecks. We first generate the previous definitions again:\ \>", "Text", CellChangeTimes->{{3.4409319388827724`*^9, 3.440931956838592*^9}, { 3.440932117689885*^9, 3.4409321373781953`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{ RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test", ",", "rhsF"}], "]"}], ";", RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test1", ",", "rhsF2"}], "]"}]}]], "Input", CellChangeTimes->{{3.440931914708011*^9, 3.440931929779683*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test1", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF2", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test1", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF2", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test1", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF2", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"} ]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "z", ",", "t", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{ RowBox[{"(", RowBox[{"x", "+", "y"}], ")"}], " ", RowBox[{"(", RowBox[{"z", "-", "t"}], ")"}]}]}]}], "}"}]], "Output", CellChangeTimes->{3.4418082847621202`*^9, 3.441814416118578*^9}] }, Open ]], Cell["Now we remove all added definitions :", "Text", CellChangeTimes->{{3.4409320761000814`*^9, 3.4409320898097954`*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"RemoveAllOptionsChecks", "[", "f", "]"}]], "Input", CellChangeTimes->{{3.440932091171754*^9, 3.4409320981017184`*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_", ",", "t_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{ RowBox[{"(", RowBox[{"x", "+", "y"}], ")"}], " ", RowBox[{"(", RowBox[{"z", "-", "t"}], ")"}]}]}]}], "}"}]], "Output", CellChangeTimes->{3.4418082876562815`*^9, 3.4418144180012846`*^9}] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell["Side-effect safety", "Subsection", CellChangeTimes->{{3.4418090404187007`*^9, 3.4418090457463617`*^9}}, FontWeight->"Plain"], Cell["\<\ In case of conditional patterns, the conditions attached to function's \ signatures are ignored in new option-checking definitions. This is \ intentional since I presumed that they should not be checked in our \ error-checking definitions. They are irrelevant for the error-checking and \ in addition, can contain side effects. Consider the following example :\ \>", "Text", CellChangeTimes->{{3.4409258558658237`*^9, 3.440925907810517*^9}, { 3.4409292686932287`*^9, 3.440929290935211*^9}, {3.440929364300706*^9, 3.440929370048971*^9}, {3.44093110581488*^9, 3.440931262610341*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"Clear", "[", RowBox[{"f", ",", "n"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"n", "=", "0"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"Or", "[", RowBox[{ RowBox[{"n", "++"}], ",", RowBox[{"EvenQ", "[", "x", "]"}]}], "]"}]}], ":=", RowBox[{"x", "^", "2"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], ":=", RowBox[{"x", "+", "y"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], ":=", RowBox[{"x", "*", "y", "*", "z"}]}], ";"}]}], "Input", CellChangeTimes->{{3.4407557112035537`*^9, 3.4407557464041696`*^9}, { 3.4407744239211197`*^9, 3.440774428557787*^9}, {3.440925069865611*^9, 3.4409250759042945`*^9}, {3.4409256321841855`*^9, 3.440925648818104*^9}}, FontWeight->"Plain"], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"3", ",", RowBox[{"FontSize", "\[Rule]", " ", "5"}]}], "]"}]], "Input", CellChangeTimes->{{3.4409254917322254`*^9, 3.4409255096079297`*^9}}], Cell[BoxData[ RowBox[{"3", "+", RowBox[{"(", RowBox[{"FontSize", "\[Rule]", "5"}], ")"}]}]], "Output", CellChangeTimes->{3.441808292373064*^9, 3.441814429377643*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData["n"], "Input", CellChangeTimes->{3.4409256749957457`*^9}], Cell[BoxData["1"], "Output", CellChangeTimes->{3.441808293394533*^9, 3.4418144307295876`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"4", ",", RowBox[{"FontSize", "\[Rule]", " ", "5"}]}], "]"}]], "Input", CellChangeTimes->{{3.440925524088752*^9, 3.4409255248798895`*^9}, { 3.440929404638709*^9, 3.44092940571025*^9}}], Cell[BoxData["16"], "Output", CellChangeTimes->{3.4418082973201776`*^9, 3.4418144324720926`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData["n"], "Input", CellChangeTimes->{3.440925714853058*^9}], Cell[BoxData["2"], "Output", CellChangeTimes->{{3.4418082990126114`*^9, 3.441808303959725*^9}, 3.441814433643778*^9}] }, Open ]], Cell["We now add the checking definitions :", "Text", CellChangeTimes->{{3.4409294131709776`*^9, 3.440929421793376*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"Clear", "[", RowBox[{"f", ",", "n"}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"n", "=", "0"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"Or", "[", RowBox[{ RowBox[{"n", "++"}], ",", RowBox[{"EvenQ", "[", "x", "]"}]}], "]"}]}], ":=", RowBox[{"x", "^", "2"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], ":=", RowBox[{"x", "+", "y"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], ":=", RowBox[{"x", "*", "y", "*", "z"}]}], ";"}]}], "Input", CellChangeTimes->{{3.4407557112035537`*^9, 3.4407557464041696`*^9}, { 3.4407744239211197`*^9, 3.440774428557787*^9}, {3.440925069865611*^9, 3.4409250759042945`*^9}, {3.4409256321841855`*^9, 3.440925648818104*^9}}, FontWeight->"Plain"], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test", ",", "rhsF"}], "]"}]], "Input", CellChangeTimes->{{3.440929451335856*^9, 3.440929452838016*^9}}], Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], "]"}], "\[RuleDelayed]", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{ RowBox[{"n", "++"}], "||", RowBox[{"EvenQ", "[", "x", "]"}]}]}], "]"}], "\[RuleDelayed]", SuperscriptBox["x", "2"]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", "+", "y"}]}], ",", RowBox[{ RowBox[{"HoldPattern", "[", RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], "]"}], "\[RuleDelayed]", RowBox[{"x", " ", "y", " ", "z"}]}]}], "}"}]], "Output", CellChangeTimes->{3.4418083082058306`*^9, 3.4418144404034977`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"3", ",", RowBox[{"FontSize", "\[Rule]", " ", "5"}]}], "]"}]], "Input", CellChangeTimes->{{3.4409254917322254`*^9, 3.4409255096079297`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"f", "::", "\<\"badopt\"\>"}], RowBox[{":", " "}], "\<\"Inappropriate option\"\>"}]], "Message", CellChangeTimes->{3.4418083109097185`*^9, 3.4418144425165358`*^9}], Cell[BoxData["$Failed"], "Output", CellChangeTimes->{3.4418083109497757`*^9, 3.441814442556594*^9}] }, Open ]], Cell["\<\ In this case, < n > has not been incremented, as it probably should have been \ since the corresponding original definition has not been invoked.\ \>", "Text", CellChangeTimes->{{3.440929550248085*^9, 3.4409296023930655`*^9}}], Cell[CellGroupData[{ Cell[BoxData["n"], "Input", CellChangeTimes->{3.4409256749957457`*^9}], Cell[BoxData["0"], "Output", CellChangeTimes->{3.441808312852512*^9, 3.441814444038725*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"3", ",", RowBox[{"FontWeight", "\[Rule]", " ", "Bold"}]}], "]"}]], "Input", CellChangeTimes->{{3.4409296263675394`*^9, 3.440929629622219*^9}}], Cell[BoxData[ RowBox[{"3", "+", RowBox[{"(", RowBox[{"FontWeight", "\[Rule]", "Bold"}], ")"}]}]], "Output", CellChangeTimes->{3.4418083138639665`*^9, 3.441814455915803*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData["n"], "Input", CellChangeTimes->{3.44092963228605*^9}], Cell[BoxData["1"], "Output", CellChangeTimes->{3.441808315255968*^9, 3.4418144574980783`*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"f", "[", RowBox[{"4", ",", RowBox[{"FontSize", "\[Rule]", " ", "5"}]}], "]"}]], "Input", CellChangeTimes->{{3.440925524088752*^9, 3.4409255248798895`*^9}, { 3.440929404638709*^9, 3.44092940571025*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"f", "::", "\<\"badopt\"\>"}], RowBox[{":", " "}], "\<\"Inappropriate option\"\>"}]], "Message", CellChangeTimes->{3.441808316657984*^9, 3.441814458489504*^9}], Cell[BoxData["$Failed"], "Output", CellChangeTimes->{3.441808316698042*^9, 3.441814458509533*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData["n"], "Input", CellChangeTimes->{3.440925714853058*^9}], Cell[BoxData["1"], "Output", CellChangeTimes->{3.441808318660864*^9, 3.441814459861477*^9}] }, Open ]], Cell["These are the current definitions for < f > :", "Text", CellChangeTimes->{{3.440934516949851*^9, 3.440934530258989*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"?", "f"}]], "Input", CellChangeTimes->{{3.4409345118124638`*^9, 3.4409345120327806`*^9}}], Cell[CellGroupData[{ Cell["Global`f", "Print", "PrintUsage", CellChangeTimes->{3.441814461994544*^9}, CellTags->"Info3441785661-2317127"], Cell[BoxData[ InterpretationBox[GridBox[{ {GridBox[{ { RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}], ":=", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "opts"}], "]"}]}], "]"}]}]}, {" "}, { RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{"test", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}], ":=", RowBox[{"rhsF", "[", RowBox[{"f", ",", RowBox[{"Hold", "[", "opts", "]"}], ",", RowBox[{"Hold", "[", RowBox[{"x", ",", "y", ",", "opts"}], "]"}]}], "]"}]}]}, {" "}, { RowBox[{ RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], "/;", RowBox[{ RowBox[{"n", "++"}], "||", RowBox[{"EvenQ", "[", "x", "]"}]}]}], ":=", SuperscriptBox["x", "2"]}]}, {" "}, { RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", RowBox[{"opts___", "?", "OptionQ"}]}], "]"}], ":=", RowBox[{"x", "+", "y"}]}]}, {" "}, { RowBox[{ RowBox[{"f", "[", RowBox[{"x_", ",", "y_", ",", "z_"}], "]"}], ":=", RowBox[{"x", " ", "y", " ", "z"}]}]} }, BaselinePosition->{Baseline, {1, 1}}, GridBoxAlignment->{ "Columns" -> {{Left}}, "ColumnsIndexed" -> {}, "Rows" -> {{Baseline}}, "RowsIndexed" -> {}}, GridBoxItemSize->{"Columns" -> {{ Scaled[0.999]}}, "ColumnsIndexed" -> {}, "Rows" -> {{1.}}, "RowsIndexed" -> {}}]} }, BaselinePosition->{Baseline, {1, 1}}, GridBoxAlignment->{ "Columns" -> {{Left}}, "ColumnsIndexed" -> {}, "Rows" -> {{Baseline}}, "RowsIndexed" -> {}}], Definition["f"], Editable->False]], "Print", CellChangeTimes->{3.441814462024587*^9}, CellTags->"Info3441785661-2317127"] }, Open ]] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell["Protected functions", "Subsection", CellChangeTimes->{{3.4418090804162145`*^9, 3.4418090840614557`*^9}}, FontWeight->"Plain"], Cell["\<\ The package' s functions won' t work on Protected functions :\ \>", "Text", CellChangeTimes->{{3.440934536027283*^9, 3.4409345516197042`*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"Protect", "[", "f", "]"}], ";"}]], "Input", CellChangeTimes->{{3.440934553452339*^9, 3.440934556076112*^9}}], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test1", ",", "rhsF1"}], "]"}]], "Input", CellChangeTimes->{{3.440934570717165*^9, 3.440934571478259*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"AddOptionsCheck", "::", "\<\"prtctd\"\>"}], RowBox[{ ":", " "}], "\<\"The function \\!\\(f\\) is Protected. It has to be \ Unprotected first\"\>"}]], "Message", CellChangeTimes->{3.441808668784317*^9, 3.441814472329405*^9}], Cell[BoxData[ RowBox[{"AddOptionsCheck", "[", RowBox[{"f", ",", "test1", ",", "rhsF1"}], "]"}]], "Output", CellChangeTimes->{3.4418086688444033`*^9, 3.441814472359448*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"RemoveOptionsCheck", "[", RowBox[{"f", ",", "test"}], "]"}]], "Input", CellChangeTimes->{3.4409349693904285`*^9}], Cell[BoxData[ RowBox[{ RowBox[{"RemoveOptionsCheck", "::", "\<\"prtctd\"\>"}], RowBox[{ ":", " "}], "\<\"The function \\!\\(f\\) is Protected. It has to be \ Unprotected first\"\>"}]], "Message", CellChangeTimes->{3.4418086716985073`*^9, 3.441814474142011*^9}], Cell[BoxData[ RowBox[{"RemoveOptionsCheck", "[", RowBox[{"f", ",", "test"}], "]"}]], "Output", CellChangeTimes->{3.441808671718536*^9, 3.441814474182069*^9}] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ RowBox[{"RemoveAllOptionsChecks", "[", "f", "]"}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{"RemoveAllOptionsChecks", "::", "\<\"prtctd\"\>"}], RowBox[{ ":", " "}], "\<\"The function \\!\\(f\\) is Protected. It has to be \ Unprotected first\"\>"}]], "Message", CellChangeTimes->{3.4418086759646416`*^9, 3.4418144758044014`*^9}], Cell[BoxData[ RowBox[{"RemoveAllOptionsChecks", "[", "f", "]"}]], "Output", CellChangeTimes->{3.4418086759846706`*^9, 3.441814475834445*^9}] }, Open ]], Cell[BoxData[{ RowBox[{ RowBox[{"Unprotect", "[", "f", "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"ClearAll", "[", RowBox[{"f", ",", "n", ",", "test", ",", "rhsF"}], "]"}], ";"}]}], "Input",\ CellChangeTimes->{{3.4409305374075503`*^9, 3.4409305476022096`*^9}, { 3.4409350058027873`*^9, 3.4409350100188494`*^9}, {3.4409350429962687`*^9, 3.440935060631627*^9}}] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Summary", "Section", CellChangeTimes->{{3.441809140642816*^9, 3.4418091437873373`*^9}}, FontWeight->"Plain"], Cell[TextData[{ "The package allows one to add new definitions to option - receiving \ functions. These new definitions will be tried before the old ones and can \ check passed options for validity, testing both option name and its r.h.s. \ The tests (testing function) are specified by the user of the package. In \ case of option considered \"inappropriate\", the code (response function) \ specified by the user will be executed. In this case, it is not possible to \ return the function in questions unevaluated (which is a usual ", StyleBox["Mathematica", FontSlant->"Italic"], " programming convention for responding to bad arguments). In case of \ inappropriate option passed, the \"response\" code executes and the \ \"initial\" definitions are not executed at all. \n\nThe functionality of \ this package is supposed to complement the standard option-filtering done \ with the help of FilterOptions/FilterRules. At present, the main pre - \ requisite for this to work is that all option - taking functions to be \ protected have in their signature (s) options declared as ", StyleBox["opts___?OptionQ", FontWeight->"Bold", FontSlant->"Italic"], " (name < opts > can be arbitrary). The constructs ", StyleBox["OptionPattern", FontWeight->"Bold", FontSlant->"Italic"], " - ", StyleBox["OptionValue", FontWeight->"Bold", FontSlant->"Italic"], ", introduced in v.6.0, are not yet covered.\n\nThe package has 2 functions \ for setting/removing the \"protection\": ", StyleBox["AddOptionsCheck", FontWeight->"Bold", FontSlant->"Italic"], " and ", StyleBox["RemoveOptionsCheck", FontWeight->"Bold", FontSlant->"Italic"], StyleBox[". ", FontSlant->"Italic"], "One has to prepare testing and response function, which become arguments of \ the functions just mentioned. There is also a predicate to test for the \ protection status, ", StyleBox["OptionIsChecked", FontWeight->"Bold", FontSlant->"Italic"], ".\n\nOne can add checks associated with other testing function(s). When the \ \"protected\" function is called, the tests associated with the last-added \ testing function, are executed first. All testing functions must be symbols \ rather than pure functions. Response functions are free from this limitation. \ For testing functions, and for response functions whose head is Symbol \ (DownValue-based), it is not required that they are actually defined before \ using ", StyleBox["AddOptionsCheck", FontWeight->"Bold", FontSlant->"Italic"], " - it is only important that they are defined before the function being \ protected will be called. Both testing and response functions have specific \ format, receiving 3 arguments: the name of the function to be protected, \ options passed to it, wrapped in Hold, and a full sequence of arguments \ passed to , also wrapped in Hold. It may not be necessary to use all of \ these in all cases, but they provide the most complete information regarding \ the function's call. Testing function should give False for correct input and \ True for incorrect one. All inputs on which the test function does not \ explicitly evaluate to True, are considered correct. \n\nOne can also \ selectively remove testing definitions associated with specific testing \ functions. If all testing tefinitions, associated with all introduced testing \ functions, have to be removed at once, the ", StyleBox["RemoveAllOptionsChecks", FontWeight->"Bold", FontSlant->"Italic"], " function can be used. The result should be that the function being \ protected returns completely to its original form (having only the original \ definitions left).\n\nThe new definitions are side-effect safe (that is, they \ do not introduce new side effects), for functions without side effects placed \ inside their main signatures f[args___] (conditions attached as ", StyleBox["f[args___]/;cond := rhs", FontSlant->"Italic"], " or ", StyleBox["f[args___] := rhs/;cond ", FontSlant->"Italic"], " are not considered part of the main signature, and may contain side \ effects). They can, however, slow down the function being \"protected\", \ especially if the latter is not computationally demanding and is frequently \ called. Even in such cases, one can use the \"protection\" temporarily for \ debugging purposes.\n\nThere may exist cases where the present functionality \ will not go well with the initial one of the function being protected. Mostly \ this may happen if the protected function's (or some other related \ function's) implementation involves direct run-time manipulations with \ DownValues of the function being protected. It is my guess (or hope) that the \ majority of functions are written in a more \"traditional\" style and do not \ fall into this category.\n\nIn case if one wishes to apply the present \ functionality to Protected function (the one having the Protected Attribute), \ one has to Unprotect it first. \n\n" }], "Text", CellChangeTimes->{{3.441809862480768*^9, 3.4418101322887325`*^9}, { 3.4418101877184367`*^9, 3.4418102749939327`*^9}, {3.4418103110057154`*^9, 3.441811090035906*^9}, {3.4418111236742754`*^9, 3.441811376888379*^9}, { 3.4418114193594494`*^9, 3.4418116197075357`*^9}, {3.441811651553328*^9, 3.4418117676302385`*^9}, {3.4418118496982465`*^9, 3.441811997731107*^9}, { 3.441812079017992*^9, 3.4418121433705263`*^9}, {3.44181224320408*^9, 3.441812317010208*^9}, {3.441812348805928*^9, 3.441812350428261*^9}, { 3.4418123933099213`*^9, 3.4418123938306704`*^9}, {3.4418124557697344`*^9, 3.4418124575823407`*^9}, 3.441814319369459*^9}] }, Closed]] }, Open ]] }, WindowSize->{1016, 651}, WindowMargins->{{0, Automatic}, {Automatic, 0}}, ShowSelection->True, Magnification->1.5, FrontEndVersion->"6.0 for Microsoft Windows (32-bit) (April 28, 2007)", StyleDefinitions->"Default.nb" ] (* End of Notebook Content *) (* Internal cache information *) (*CellTagsOutline CellTagsIndex->{ "Info3441785661-2317127"->{ Cell[56209, 1702, 118, 2, 60, "Print", CellTags->"Info3441785661-2317127"], Cell[56330, 1706, 2635, 76, 247, "Print", CellTags->"Info3441785661-2317127"]} } *) (*CellTagsIndex CellTagsIndex->{ {"Info3441785661-2317127", 67813, 2000} } *) (*NotebookFileOutline Notebook[{ Cell[CellGroupData[{ Cell[590, 23, 389, 8, 117, "Subtitle"], Cell[CellGroupData[{ Cell[1006, 36, 278, 9, 156, "Subsection"], Cell[1287, 47, 147, 2, 41, "Subsubsection"], Cell[1437, 51, 271, 7, 31, "Subsubsection"] }, Open ]], Cell[CellGroupData[{ Cell[1745, 63, 121, 2, 105, "Section"], Cell[1869, 67, 2117, 44, 436, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[4023, 116, 121, 2, 58, "Section"], Cell[CellGroupData[{ Cell[4169, 122, 125, 2, 54, "Subsection"], Cell[4297, 126, 235, 5, 41, "Text"], Cell[4535, 133, 394, 10, 118, "Input"], Cell[4932, 145, 102, 1, 41, "Text"], Cell[5037, 148, 161, 3, 43, "Input"], Cell[5201, 153, 99, 1, 41, "Text"], Cell[CellGroupData[{ Cell[5325, 158, 101, 2, 43, "Input"], Cell[5429, 162, 1638, 47, 99, "Print"] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell[7116, 215, 150, 2, 40, "Subsection"], Cell[7269, 219, 113, 1, 41, "Text"], Cell[7385, 222, 834, 23, 118, "Input"], Cell[8222, 247, 292, 6, 41, "Text"], Cell[8517, 255, 983, 27, 125, "Input"], Cell[9503, 284, 126, 1, 41, "Text"], Cell[CellGroupData[{ Cell[9654, 289, 173, 3, 43, "Input"], Cell[9830, 294, 1941, 56, 205, "Output"] }, Open ]], Cell[11786, 353, 117, 1, 41, "Text"], Cell[CellGroupData[{ Cell[11928, 358, 124, 2, 43, "Input"], Cell[12055, 362, 94, 1, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[12186, 368, 185, 4, 43, "Input"], Cell[12374, 374, 96, 1, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[12507, 380, 285, 6, 43, "Input"], Cell[12795, 388, 196, 4, 32, "Message"], Cell[12994, 394, 98, 1, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[13129, 400, 195, 4, 43, "Input"], Cell[13327, 406, 116, 2, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[13480, 413, 246, 5, 43, "Input"], Cell[13729, 420, 116, 2, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[13882, 427, 350, 7, 43, "Input"], Cell[14235, 436, 201, 4, 32, "Message"], Cell[14439, 442, 100, 1, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[14576, 448, 162, 3, 43, "Input"], Cell[14741, 453, 99, 1, 42, "Output"] }, Open ]], Cell[14855, 457, 179, 4, 41, "Text"], Cell[CellGroupData[{ Cell[15059, 465, 253, 5, 43, "Input"], Cell[15315, 472, 115, 2, 42, "Output"] }, Open ]], Cell[15445, 477, 1169, 18, 262, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[16651, 500, 148, 2, 40, "Subsection"], Cell[16802, 504, 259, 5, 41, "Text"], Cell[CellGroupData[{ Cell[17086, 513, 107, 2, 43, "Input"], Cell[17196, 517, 1943, 56, 205, "Output"] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell[19188, 579, 166, 2, 40, "Subsection"], Cell[19357, 583, 123, 1, 41, "Text"], Cell[19483, 586, 383, 11, 43, "Input"], Cell[19869, 599, 278, 5, 66, "Text"], Cell[CellGroupData[{ Cell[20172, 608, 131, 2, 43, "Input"], Cell[20306, 612, 2298, 67, 230, "Output"] }, Open ]], Cell[22619, 682, 121, 1, 41, "Text"], Cell[CellGroupData[{ Cell[22765, 687, 107, 2, 43, "Input"], Cell[22875, 691, 2975, 85, 305, "Output"] }, Open ]], Cell[25865, 779, 253, 5, 66, "Text"], Cell[CellGroupData[{ Cell[26143, 788, 107, 2, 43, "Input"], Cell[26253, 792, 2975, 85, 305, "Output"] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell[29277, 883, 153, 2, 40, "Subsection"], Cell[29433, 887, 342, 6, 66, "Text"], Cell[CellGroupData[{ Cell[29800, 897, 179, 3, 43, "Input"], Cell[29982, 902, 4845, 137, 480, "Output"] }, Open ]], Cell[34842, 1042, 215, 3, 41, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[35094, 1050, 141, 2, 40, "Subsection"], Cell[35238, 1054, 239, 4, 41, "Text"], Cell[CellGroupData[{ Cell[35502, 1062, 167, 3, 43, "Input"], Cell[35672, 1067, 2981, 85, 305, "Output"] }, Open ]], Cell[38668, 1155, 115, 1, 41, "Text"], Cell[CellGroupData[{ Cell[38808, 1160, 142, 3, 43, "Input"], Cell[38953, 1165, 1111, 33, 128, "Output"] }, Open ]], Cell[40079, 1201, 283, 5, 66, "Text"], Cell[CellGroupData[{ Cell[40387, 1210, 281, 6, 43, "Input"], Cell[40671, 1218, 4845, 137, 480, "Output"] }, Open ]], Cell[45531, 1358, 123, 1, 41, "Text"], Cell[CellGroupData[{ Cell[45679, 1363, 143, 2, 43, "Input"], Cell[45825, 1367, 1113, 33, 128, "Output"] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell[46987, 1406, 132, 2, 40, "Subsection"], Cell[47122, 1410, 599, 9, 90, "Text"], Cell[47724, 1421, 1109, 31, 143, "Input"], Cell[CellGroupData[{ Cell[48858, 1456, 189, 4, 43, "Input"], Cell[49050, 1462, 174, 4, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[49261, 1471, 71, 1, 43, "Input"], Cell[49335, 1474, 94, 1, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[49466, 1480, 235, 5, 43, "Input"], Cell[49704, 1487, 97, 1, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[49838, 1493, 69, 1, 43, "Input"], Cell[49910, 1496, 122, 2, 42, "Output"] }, Open ]], Cell[50047, 1501, 121, 1, 41, "Text"], Cell[50171, 1504, 1109, 31, 143, "Input"], Cell[CellGroupData[{ Cell[51305, 1539, 173, 3, 43, "Input"], Cell[51481, 1544, 2057, 59, 205, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[53575, 1608, 189, 4, 43, "Input"], Cell[53767, 1614, 201, 4, 32, "Message"], Cell[53971, 1620, 100, 1, 42, "Output"] }, Open ]], Cell[54086, 1624, 237, 4, 66, "Text"], Cell[CellGroupData[{ Cell[54348, 1632, 71, 1, 43, "Input"], Cell[54422, 1635, 92, 1, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[54551, 1641, 192, 4, 43, "Input"], Cell[54746, 1647, 181, 4, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[54964, 1656, 68, 1, 43, "Input"], Cell[55035, 1659, 94, 1, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[55166, 1665, 235, 5, 43, "Input"], Cell[55404, 1672, 197, 4, 32, "Message"], Cell[55604, 1678, 98, 1, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[55739, 1684, 69, 1, 43, "Input"], Cell[55811, 1687, 92, 1, 42, "Output"] }, Open ]], Cell[55918, 1691, 127, 1, 41, "Text"], Cell[CellGroupData[{ Cell[56070, 1696, 114, 2, 43, "Input"], Cell[CellGroupData[{ Cell[56209, 1702, 118, 2, 60, "Print", CellTags->"Info3441785661-2317127"], Cell[56330, 1706, 2635, 76, 247, "Print", CellTags->"Info3441785661-2317127"] }, Open ]] }, Open ]] }, Closed]], Cell[CellGroupData[{ Cell[59026, 1789, 133, 2, 40, "Subsection"], Cell[59162, 1793, 153, 3, 41, "Text"], Cell[59318, 1798, 144, 3, 43, "Input"], Cell[CellGroupData[{ Cell[59487, 1805, 175, 3, 43, "Input"], Cell[59665, 1810, 264, 6, 32, "Message"], Cell[59932, 1818, 176, 3, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[60145, 1826, 141, 3, 43, "Input"], Cell[60289, 1831, 269, 6, 58, "Message"], Cell[60561, 1839, 162, 3, 42, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[60760, 1847, 75, 1, 43, "Input"], Cell[60838, 1850, 275, 6, 58, "Message"], Cell[61116, 1858, 142, 2, 42, "Output"] }, Open ]], Cell[61273, 1863, 388, 9, 71, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[61710, 1878, 116, 2, 58, "Section"], Cell[61829, 1882, 5610, 102, 1174, "Text"] }, Closed]] }, Open ]] } ] *) (* End of internal cache information *)