Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

OptionValue allows for recent versions of Mathematica (I think as from 7) to easily access optional parameters if they are explicitely given to a function or their default values otherwise.

For big functions using options of options can be useful but we don't have in such cases something like OptionValue in order to access them. We must resort to using Replace in order to use them.

See for example the option "LegendGridOptions" in the answer of Jens to the question Creating legends for plots with multiple lines?

"LegendGridOptions" -> {Alignment -> Left, Spacings -> {.4, .1}}}

Has someone already tried to do something like OptionValue for sub-options ?

share|improve this question
1  
In particular, I think Mr Wizard's answer to my earlier question is what you want. –  Verbeia Apr 25 '12 at 23:35
    
There is another option: feed the options to an internal function. This internal function should be set up with an Options[...]= clause, also. Then, it is the sub-function's job to respond to the options. –  rcollyer Apr 26 '12 at 0:22
4  
I disagree that this is an exact duplicate. While the answer for the question mentioned might be the same, the question is not. The focus of that question is on JASON and not option parsing. –  user21 Apr 26 '12 at 5:26
    
@Faysal Aberkane, if the answer in link does not help, I have another idea, send me an email and I'll send it to you. –  user21 Apr 26 '12 at 5:37
    
OK, both answers of Mr Wizard and Heike help, thanks. @ruebenko, I'm still curious about your idea though ! –  Faysal Aberkane Apr 26 '12 at 9:01

3 Answers 3

up vote 9 down vote accepted

You can actually use OptionValue to extract options of options by doing something like OptionValue[option -> subOption]. For example

Options[ff] = {"fruit" -> {apple -> 1, pear -> 2, orange -> 3}}
ff[OptionsPattern[]] := {apple, OptionValue["fruit" -> apple]}

ff["fruit" -> {apple -> 4}]

(* ==> {apple, 4} *)
share|improve this answer

Elaborating on Heike's suggestion here is an example where functions with different options call each other:

ClearAll[gg, ff]
Options[gg] = {apple -> 1, pear -> 2, orange -> 3}
Options[ff] = {"blah" -> blub, "fruit" -> Options[gg]}

ff[opts : OptionsPattern[ff]] := Block[{},
  Print[OptionValue["blah"]];
  Print[OptionValue["fruit"]];
  gg[OptionValue["fruit"]];
  ]
gg[OptionsPattern[gg]] := Block[{},
  Print[OptionValue[pear]];
  ]

Then

ff[]
(*
blub
{apple -> 1, pear -> 2, orange -> 3}
2 
*)

And

ff["fruit" -> {pear -> 22}]
(*
blub
{pear -> 22}
22
*)

And

gg[pear -> 22]
(*22*)
share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.