4

Consider this function.

Options[foo]={WorkingPrecision->MachinePrecision};
SyntaxInformation[foo]={"ArgumentsPattern"->{_,OptionsPattern[]}};
foo[expr_,OptionsPattern[foo]]:=
  With[{prec=OptionValue@WorkingPrecision},
  If[TrueQ[0<prec<=Infinity],N[expr,prec],(* else *)Indeterminate]
];

In this case it does what I want. This works.

But when given invalid options, foo should display a message and return what it was given. This is an example. Also want this.

The Message above can be displayed using this:

Message[foo::optx,PlotRange,
  Inactive@foo[Sqrt[2],WorkingPrecision->20,PlotRange->All]
]

So how do I get my code to find the invalid option and return the expression it was given?

Ted Ersek
  • 919
  • 2
  • 9

2 Answers2

5

CheckArguments was mentioned in a comment, here is how you can modify your code to use it:

ClearAll @ foo;
Options[foo] = {WorkingPrecision -> MachinePrecision};
SyntaxInformation[foo] = {"ArgumentsPattern" -> {_, OptionsPattern[]}};
foo[expr_, o:OptionsPattern[]] /; CheckArguments[foo[expr, o], 1] := With[
    {prec = OptionValue @ WorkingPrecision},
    If[TrueQ[0 < prec <= Infinity],
        N[expr, prec],
        Indeterminate
    ]
];

The pattern /; condition on the left hand side of the := is the key to returning unevaluated.

In[45]:= foo[Sqrt[2], WorkingPrecision -> 20]

Out[45]= 1.4142135623730950488

In[46]:= foo[Sqrt[2], WorkingPrecision -> 20, PlotRange -> All]

During evaluation of In[46]:= foo::optx: Unknown option PlotRange in foo[Sqrt[2],WorkingPrecision->20,PlotRange->All].

Out[46]= foo[Sqrt[2], WorkingPrecision -> 20, PlotRange -> All]

Jason B.
  • 68,381
  • 3
  • 139
  • 286
1

This does almost exactly what I asked for

Options[foo]={WorkingPrecision->MachinePrecision};
SyntaxInformation[foo]={"ArgumentsPattern"->{_,OptionsPattern[]}};
foo[expr_,OptionsPattern[foo]]:=Module[{prec,validOptions},
  {prec,validOptions}=Check[{OptionValue[WorkingPrecision],True},{0,False},OptionValue::nodef];
  Which[
    (* Test 1 *)Infinity===prec,expr,
    (* Test 2 *)TrueQ[0<prec<=Infinity],N[expr,prec],
    (* Test 3 *)True,Indeterminate
  ]/;validOptions
];

Now for a screenshot showing how it works.

screenshot

The second example in the screenshot made the Message. That is good enough, but I still wonder how I could get the names of the invalid options and use them in my Message.

Ted Ersek
  • 919
  • 2
  • 9