a technique for options
- To: mathgroup at smc.vnet.net
- Subject: [mg71585] a technique for options
- From: "Chris Chiasson" <chris at chiasson.name>
- Date: Fri, 24 Nov 2006 01:17:05 -0500 (EST)
I noticed this a few months ago, but I am just getting around to
programming this way, and I'd like to share it with you:
OptionQ evaluates to True for an option or a list of options. A lot of
built in functions can handle their options given as lists:
Plot[x,{x,0,1},{PlotStyle->Blue}]
However, users (myself included), seem to be writing code that ignores
this aspect of option handling. I blame this ( like all my other
Mathematica failings :-] ) squarely on the documentation, specifically
section 2.3.10.
BTW, I just noticed that OptionQ, like StringQ, does not have a help
browser entry.
Here is an example from that section on writing functions that take options:
-----------------------------------------------------------------
f[x_, opts___] := value
a typical definition for a function with zero or more named optional arguments
name/.{opts}/.Options[f]
replacements used to get the value of a named optional argument in the
body of the function
-----------------------------------------------------------------
There are two things "wrong" with the example. The first, and
non-serious, problem is that the named pattern opts isn't checked with
OptionQ. The second, and more serious, problem is that the result of
name/.{opts}/.Options[f] will likely be different if the user feeds an
option list to the function instead of the expected option sequence.
People may feel that it is a waste of time to support such a calling
convention, but it is actually rather easy to do robustly, AFAIK.
The technique involves the exploitation of Flatten (and the fact that
rules aren't lists)... Here is an example:
Options[f]={Precision->40};
f[x_,callOpts___?OptionQ]:=
With[{opts=Flatten[{callOpts,Options[f]}]},N[x,Precision/.opts]]
f[5]
f[5,Precision->10]
f[5,{Precision->20}]
5.000000000000000000000000000000000000000
5.000000000
5.0000000000000000000
Here is what would happen on the last call if the user chose the
technique in the Mathematica Book:
System`Dump`$MessagesInHelpBrowserAreKnown=False;
N[5,Precision/.{{Precision->20}}/.Options@f]
N::arg: Argument {20} is not of the form {precision, accuracy}.
N[5,{20}]
--
http://chris.chiasson.name/