1
$\begingroup$

How do i safely, efficiently, and elegantly select compatible options?

I normally do

foo[opts:OptionsPattern[]] := Module[
    {goodOpts},
    goodOpts = FilterRules[{opts}, Options[bar][[All,1]]];
    bar[goodOpts]
]

Is there any loophole where this can cause bugs?

Is there a more efficient and more elegant way?

$\endgroup$
3
  • $\begingroup$ I don't think there's any difference between that and goodOpts=FilterRules[{opts},Options[bar]], and the assignment can be made in the first argument of module. $\endgroup$
    – C. E.
    Commented Aug 23, 2013 at 18:09
  • $\begingroup$ This is possibly a duplicate of (353), especially my answer there. $\endgroup$
    – Mr.Wizard
    Commented Aug 23, 2013 at 20:03
  • $\begingroup$ Also for the reason described specifically in (20470) you should be using opts : OptionsPattern[{foo, bar}] assuming foo itself takes options. $\endgroup$
    – Mr.Wizard
    Commented Aug 23, 2013 at 20:36

1 Answer 1

1
$\begingroup$

I my opinion, this is exactly the way to go. As pointed out by Anon you can do the assignment directly in the variable list of Module, but otherwise it is equivalent to the example shown in the Setting Up Functions with Optional Arguments tutorial:

odeplot[de_, y_, {x_, x0_, x1_}, opts : OptionsPattern[]] := 
 Module[{sol},
  sol = NDSolve[de, y, {x, x0, x1}, 
    FilterRules[{opts}, Options[NDSolve]]];
  If[Head[sol] === NDSolve,
   $Failed,
   Plot[Evaluate[y /. sol], {x, x0, x1}, 
    Evaluate[FilterRules[{opts}, Options[Plot]]]]
   ]
  ]

A nice thing of FilterRules is that it even works with nested option lists, which is often possible in Mathematica

Plot[2 x, {x, 0, 1}, {ColorFunction -> Hue, {ColorFunctionScaling -> False}}]

This will then even work with your example

foo[opts : OptionsPattern[]] := FilterRules[{opts}, Options[Plot]]
foo[{ColorFunction -> Hue, {ColorFunctionScaling -> False, {MaxIterations -> 30}}}]
$\endgroup$
5
  • $\begingroup$ halirutan, do you feel that this question is not a duplicate? I intend(ed) to close it but since you felt it deserved an answer I don't want to be rude. $\endgroup$
    – Mr.Wizard
    Commented Aug 23, 2013 at 20:19
  • $\begingroup$ @Mr.Wizard No, I agree with you, but I wanted to point out, that this is exactly as it is suggested by the documentation. I wouldn't mind if you close it and then people still would find this specific information here and would have a link to the more general topic about how to set up functions with options. Can closed questions be found by everyone? $\endgroup$
    – halirutan
    Commented Aug 23, 2013 at 20:26
  • $\begingroup$ Okay, I think I'll do that in a while. (That gives other people a change to voice an opinion or post an answer if they feel inclined.) Yes, closed or at least duplicate questions should be visible to all and appear in searches; it is one of their functions. $\endgroup$
    – Mr.Wizard
    Commented Aug 23, 2013 at 20:33
  • $\begingroup$ The documenation for FilterRules says it try to match against the LHSs: ("FilterRules[rules,patt] filters the list rules by picking out only those rules >whose left-hand sides match patt. FilterRules[rules,{Subscript[patt, 1],Subscript[patt, 2],[Ellipsis]}] picks out >rules whose left-hand sides match any of the Subscript[patt, i].") So should not the usage be Sequence@@FilterRules[{opts}, Options[f][[All,1]]] instead of Sequence@@FilterRules[{opts}, Options[f]] ? $\endgroup$
    – user13253
    Commented Aug 26, 2013 at 16:52
  • 1
    $\begingroup$ @red3y3 Yes, but when you look in the Details section of the documentation to FilterRules you find the following statement: If any of the Subscript[patt, i] is a rule of the form lhs->rhs, then it is treated the same as lhs. Therefore, giving rules does work too. $\endgroup$
    – halirutan
    Commented Aug 26, 2013 at 18:32

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