I want to complement the other answers with a construct which allows more general manipulations of options than possible directly with OptionValue
, while still using OptionValue
for options extraction. The function, mergeOptions
, I used for my real-time code highlighter, which involves many nested options, but I will reproduce it here for completeness:
ClearAll[optionQ, mergeOptions];
optionQ[opt_] := MatchQ[opt, _Rule | _RuleDelayed];
mergeOptions[x_, y_] := mergeOptions[Null, x, y];
mergeOptions[x_, y_, x_] := y
mergeOptions[x_, fopt_?optionQ, sopts_] :=
mergeOptions[x, {fopt}, sopts];
mergeOptions[x_, fopts_, sopt_?optionQ] :=
mergeOptions[x, fopts, {sopt}];
mergeOptions[_, fopts : {__?optionQ}, sopts : {__?optionQ}] :=
Map[# -> mergeOptions[#, # /. fopts, # /. sopts] &, fopts[[All, 1]]];
mergeOptions[_, x_, y_] := y;
It allows one to merge two options trees. For example, here are two option trees:
opts1 = {
a -> {b -> {c -> cc, d -> {e, f}, g -> gg}, h -> {i -> ii, k -> {l, m}}},
n -> o,
p -> {q -> {r, s}, t -> {u, v}}
}
and
opts2 = {a -> {b -> d -> {e1, f1}, h -> i -> iii}, p -> q -> {r1, s1}}
And here is the resulting merged tree:
mergeOptions[opts1, opts2]
{
a -> {b -> {c -> cc, d -> {e1, f1}, g -> gg}, h -> {i -> iii, k -> {l, m}}},
n -> o,
p -> {q -> {r1, s1}, t -> {u, v}}
}
Note that mergeOptions
applies opts2
as a "patch" on the tree of opts1
, so effectively for those options which are present in both trees, the options for opts2
are used.
In cases when options are present in both trees, the results obtained with mergeOptions
can also be obtained directly with OptionValue
(as indicated in other answers), for example:
OptionValue[{opts2, opts1}, {a -> b -> d}]
{{e1, f1}}
OptionValue[mergeOptions[opts1, opts2], {a -> b -> d}]
{{e1, f1}}
It is when some of the options are only present in one of the trees, that mergeOptions
shows an advantage:
OptionValue[{opts2,opts1},{a->b->g}]
During evaluation of In[21]:= OptionValue::optnf: Option name a->b->g not
found in defaults for {{a->{b->d->{e1,f1},h->i->iii},p->q->{r1,s1}},
{a->{b->{c->cc,d->{<<2>>},g->gg},h->{i->ii,k->{<<2>>}}},n->o,p->{q->{r,s},
t->{u,v}}}}. >>
{a->b->g}
while with mergeOptions
we get:
OptionValue[mergeOptions[opts1, opts2], {a -> b -> g}]
{gg}
This difference is IMO of a big practical importance, since mergeOptions
allows one to selectively override only those parts of the option tree which are needed, without the need to drag all those which don't change, just to keep the same tree structure. At the same time, the use of mergeOptions
does not create any ambiguity, since the way trees are merged is completely determined by their structures. In my application (the code highlighter mentioned above), this allowed me to generate highlighter packages with really minimal explicit option specifications, since the defaults took care of most common settings, and I did not have to drag them around.
Options[...]=
clause, also. Then, it is the sub-function's job to respond to the options. $\endgroup$ – rcollyer Apr 26 '12 at 0:22