Mathematica: HOWTO: Strip an option from an OptionsPattern[] sequence before passing down (propagating) to a function with fewer options

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.
Icon class
icon_class
far fa-sticky-note
icon_class_computed
far fa-sticky-note
Note kind
Keywords

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.)

Usage:

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.
Relates to
Related notes
Related notes (backlinks)
Related snippets (extracts)
Visit also
Visit also (backlinks)