3
$\begingroup$

I have a function with Options, and I want to pass the Options to a subfunctions, including both Options with default values and Options with input values. For example, I want to pass the Options of func1 to func2:

Options[func1] = {Option1 -> DefaultValue11, Option2 -> DefaultValue12, Option3 -> DefaultValue13};
Options[func2] = {Option1 -> DefaultValue21, Option2 -> DefaultValue22};
func1[x_, opts: OptionsPattern[]] := func2[x, FilterRules[opts, Options[func2]]]
func2[x_, opts: OptionsPattern[]] := {OptionValue[Option1], OptionValue[Option2]}

In this case, if I run func1[1, Option1 -> InputValue1], then opts will only match the input option Option1 -> InputValue1, hence give:

In[1]:=func1[1, Option1 -> InputValue1]
Out[1]={InputValue1, DefaultValue22}

However, I would like something like opts: OptionsPattern[], but matching {Option1 -> InputValue1, Option2 -> DefaultValue12, Option3 -> DefaultValue13}, thus giving:

In[2]:=func1[1, Option1 -> InputValue1]
Out[2]={InputValue1, DefaultValue12}

How can I do that? Thanks in advance.

$\endgroup$

2 Answers 2

2
$\begingroup$

When you call FilterRules in the definition of func1, just include the default options for func1 after any user-supplied options:

fc[func1[x_, opts : OptionsPattern[]] := 
  func2[x, FilterRules[{opts, Options[func1]}, Options[func2]]]]

which should give the desired behavior:

In[79]:= func1[1, Option1 -> InputValue1]

Out[79]= {InputValue1, DefaultValue12}

In[81]:= func1[1, Option1 -> InputValue1, Option2 -> 13]

Out[81]= {InputValue1, 13}

I encounter this problem whenever making a plotting function: MyPlotFunction takes all the same options as Graphics, so a user should be able to call SetOptions[MyPlotFunction, ImageSize -> 100]. In my definition of MyPlotFunction then, I need to call Graphics with the correct ImageSize and FilterRules[userSuppliedOptions, Options[Graphics]] doesn't cut it.

$\endgroup$
1
  • $\begingroup$ So in this case OptionValue[Option1] will always use the first assignment Option1 -> InputValue1 and ignore the following Option1 -> DefaultValue11? $\endgroup$
    – Li Xiang
    Commented May 8 at 5:43
1
$\begingroup$

I would probably just do something like this:

func1[x_, opts : OptionsPattern[]] := Quiet[func2[x, Options[func1]], OptionValue::nodef]

But you could do a careful merge if you really wanted to. Maybe something like this:

func1[x_, opts : OptionsPattern[]] := func2[x, FilterRules[Normal@Merge[{opts, Options[func1]}, First], Options[func2]]]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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