Webel IT Australia promotes the amazing Mathematica tool and the powerful Wolfram Language and offers professional Mathematica services for computational computing and data analysis. Our Mathematica
tips, issue tracking, and wishlist is offered here most constructively to help improve the tool and language and support the Mathematica user community.
DISCLAIMER: Wolfram Research does not officially endorse analysis by Webel IT Australia.
When working with complex hierarchies of functions, sometimes the Options available to a sub-function are not as broad as those of a "parent" (higher) calling function. If you just pass down an OptionsPattern[] that is a superset of the relevant options you'll get a warning. The following shows how to strip off irrelevant options before calling down:
CASE: Strip a single option from an OptionsPattern[] Sequence:
stripOpt::usage = "stripOpt[optName,opt:OptionsPattern[]]
Strips the rule identified by optName and returns a Sequence";
stripOpt[optName_,opt:OptionsPattern[]] := If[KeyExistsQ[<|opts|>, optName],
Sequence@@Delete[{opt},Position[{opt},optName->_][[1]][[1]]],
opts
];
CASE: Strip multiple options from an OptionsPattern[] Sequence:
stripOpts::usage = "stripOpts[optName1,optName2,...,opt:OptionsPattern[]]
Strips all rules identified by optName1, optName2, etc. and returns a Sequence";
stripOpts[optNames__,opt:OptionsPattern[]] := Module[
{opts={opt},pos},
For[i=1,i<=Length[{optNames}],i++,
pos= Position[opts,{optNames}[[i]]->_];
If[Length[pos]>0,opts=Delete[opts,pos]];
];
Sequence@@ opts
];
(One could perhaps use Scan
or something more elegant than For
for the multi case, but the above works fine.)
Options[fChild] = {doThat->False};
fChild[arg_,OptionsPattern[]] := ...
Options[fParent] = {doThis->True, doThat->False};
fParent[arg_,opt:OptionsPattern[]] := Module[
fChild[arg, stripOpt[doThis,opt]]; (* Only passes valid child options *)
If[OptionValue[doThis], ...]; (* Could be before or after call to child *)
...
];
In some situations, you might like to store the parent's option value:
fParent[arg_,opt:OptionsPattern[]] := Module[
{optClean,doThis=OptionValue[doThis]}, (* Store before strip *)
optClean = stripOpt[doThis,opt];
fChild[arg, optClean]; (* Only passes valid child options *)
If[doThis,...]; (* Could be before or after call to child *)
...
];
Tracking the "cleaned" OptionsPattern with an extra variable may seem redundant here, but it can be useful if you have lots of child functions with different options.