6

I'm experimenting with options. In my first tests, I wrote something like that to capture the options given to a function:

f[opts___Rule]:= {opts}

I later descovered OptionsPattern:

f[opts:OptionsPattern[]]:= {opts}

Both seems to do the same thing and will produce the same result:

f[]
f[a->1]
f[a->1,b->2]
{}
{a->1}
{a->1,b->2}

What are the pro and cons of using opts:OptionsValues instead of opts___Rule to capture the options given to a function?

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
Sylvain Leroux
  • 1,509
  • 5
  • 15
  • 3
    OptionsPattern also accepts RuleDelayed and (nested) lists of rules. Furthermore it is clearer in intent and has very useful extra functionality when combined with OptionValue – Lukas Lang Mar 24 '20 at 15:04
  • That's a good point @Lukas. Maybe you should consider posting that as an answer? – Sylvain Leroux Mar 24 '20 at 15:19
  • 2
    I agree with Lukas's note that the OptionsPattern[]/OptionValue[] combo is quite powerful compared to the old method, but the first approach can be made more general: f[opts___?OptionQ]:= {opts}. – J. M.'s missing motivation Mar 24 '20 at 15:21
  • Thanks for the comment @J.M. Before asking I made some researches. And I occasionally saw mention of the "old way" and the "new way" of dealing with options. But without further details. For seasoned Mathematica users, that should make sense. But for me, it's a little bit confusing. What's so powerful with the "new way"? What was wrong with the "old way"? To take the same wording as in the question, those are the kind of "pros and cons" I'm looking for. – Sylvain Leroux Mar 24 '20 at 15:44

1 Answers1

4

When OptionsPattern is combined with OptionValue you get filtering and warning of improper options:

Options[f] = {a -> 1, b -> 2, c -> 3};

f[OptionsPattern[]] := {OptionValue[b]}

f[a -> 7, x -> 5]

OptionValue::nodef: Unknown option x for f. >>

{2}

You can also adopt options for/from other functions, e.g.:

f[OptionsPattern[{f, Plot}]] := {OptionValue[b], OptionValue[PlotStyle]}

f[b -> 6, PlotStyle -> None]
{6, None}

Additional examples:

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371