Trick that I sometimes find useful is "inheriting" of default option value from another symbol using delayed rule like:
optName :> OptionValue[anotherSymbol, optName]
With f
defined as:
ClearAll[f];
Options[f] = {optA -> 1, optB -> 1, optC -> 1};
f[x_, opts : OptionsPattern[]] := OptionValue[{optA, optB, optC}]
We can define g
in following way:
ClearAll[g];
(* Inherit all options from f *)
Options[g] = # :> OptionValue[f, #] & @@@ Options[f];
(* Change default values of some of them. *)
SetOptions[g, optA -> 0, optB -> 0];
g[x_, opts : OptionsPattern[]] := f[x, opts, Options[g]]
Basically it works as previous solutions
g[x]
(* {0, 0, 1} *)
g[x, optA -> 2, optC -> 2]
(* {2, 0, 2} *)
g
inherits options from f
in all situations, not only in above specific function call.
OptionValue[g, {optA, optB, optC}]
(* {0, 0, 1} *)
If you change default options of f
, then non-overridden default options of g
will inherit this change in all circumstances:
SetOptions[f, optC -> 2];
g[x]
(* {0, 0, 2} *)
OptionValue[g, {optA, optB, optC}]
(* {0, 0, 2} *)
Also at any time you can decide to change default value of any option (not only those overridden when g was defined) only on g
without affecting f
.
SetOptions[g, optC -> 0];
g[x]
(* {0, 0, 0} *)
f[x]
(* {1, 1, 2} *)
You can also, at any time, decide to use inherited option value:
SetOptions[g, optA :> OptionValue[f, optA]];
g[x]
(* {1, 0, 0} *)
Options[g] = Options[f]; SetOptions[g, {optA -> 0, optB -> 0}]
(instead of filtering). The most annoying thing for me about this solution is that if I laterSetOptions
onf
, the change won't be inherited byg
. But this is what happens with builtins too (e.g.Plot
vsGraphics
) and the workaround is rather verbose and complicated. $\endgroup$OptA -> OptionValue[OptA], optB -> OptionValue[optB]
in the call tof
is indeed necessary? $\endgroup$