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, OptionsPattern[]] 
Strips the Rule identified by 'optName' and returns a Sequence.;

stripOpt[optName_, opts:OptionsPattern[]] :=  Module[
  { map },

  If[ opts =!= Null,
    (
      map = KeyDrop[<|opts|>, optName];
      Sequence[ # -> map[#]& /@ Keys[map] ]
    ),
   (* Must be 3rd argument to If *)
    Sequence[]
  ]
];

CASE: Strip multiple options Rules from an OptionsPattern[] Sequence:

stripOpts::usage = "stripOpts[optName1, optName2,..., OptionsPattern[]] 
Strips all Rules identified by 'optName1', 'optName2', etc. and returns a Sequence";

stripOpts[optNames__,  opts:OptionsPattern[]] := Module[
  { map },

  If[opts =!= Null,
    (
      map = KeyDrop[<|opts|>, {optNames}];
      Sequence[ # -> map[#]& /@ Keys[map] ]
    ),
    (* Must be 3rd argument to If *)
    Sequence[]
  ]
];

One could perhaps uses something more elegant but the above works fine.

Note that if no OptionsPattern[] is provided it returns an "empty" Sequence[] which splices directly in.

Usage example

Options[fChild] = { doThat->False };

fChild[arg_,OptionsPattern[]] := ...

Options[fParent] = { doThis->True, doThat->False };

fParent[arg_, opts:OptionsPattern[] ] := Module[

  fChild[arg, stripOpt[doThis, opts] ]; (* Only passes valid child options *)

  If[OptionValue[doThis], ...]; (* Could be before or after call to child *)
  ...
];

Will handle all of these cases:
fParent[arg]

fParent[arg, doThis->False]

fParent[arg, doThat->True]

fParent[arg, doThis->False, doThat->True]
Relates to
Related notes
Related notes (backlinks)
Related snippets (extracts)
Visit also
Visit also (backlinks)