22
$\begingroup$

I couldn't find a more descriptive title, but I guess an example will explain my problem.

I set up some customized Grid function including some additional functionalities which I control with custom Options. Additionally, I would like to change some of the standard Grid Options, e.g. always use Frame->All. Take the following working example:

Options[myGrid] = {Frame -> All, "Tooltip" -> False};
myGrid[content_, opts : OptionsPattern[]] :=
  Module[{con},
    If[OptionValue["Tooltip"],
      con = MapIndexed[Tooltip[#1, #2] &, content, {-1}],
      con = content
    ];
    Grid[con,
      Sequence @@ 
        FilterRules[{opts}~Join~Options[myGrid], Options[Grid]]
    ]
  ]

defining an example content:

mat = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

We can test the behavior:

myGrid[mat]

Mathematica graphics

The custom "Tooltip" flag works as intended. Now I want to pass an Option to Grid, that has not been explicitely set in the above Options[myGrid] declaration.This eventually makes it through to the Grid, but produces an error message.

myGrid[mat, Background -> Blue]

Mathematica graphics

Mathematica graphics

To get rid of the errors I embed the Options from Grid into my custom function:

Options[myGrid] = 
  Join[
    {Frame -> All, "Tooltip" -> False},
    Options[Grid]
  ];

Now, I can change the Grid Options without raising an error:

myGrid[mat, Background -> Green]

Mathematica graphics

but the custom setting Frame->All gets lost.

myGrid[mat, Frame -> All]

Mathematica graphics

Apparently, the default Frame->None setting for Grid overrules my custom setting. I banged my head against this problem for too long already, therefore my plea for your assistance.

$\endgroup$

2 Answers 2

31
$\begingroup$

OptionsPattern:

Mathematica graphics

Therefore declare Options for both myGrid and Grid as valid:

Options[myGrid] = {Frame -> All, "Tooltip" -> False};

myGrid[content_, opts : OptionsPattern[{myGrid, Grid}]] := . . .

Then:

myGrid[mat, Background -> Blue]
Grid[mat, Background -> RGBColor[0, 0, 1], Frame -> All]

With no error message.

$\endgroup$
14
  • 2
    $\begingroup$ This is pretty cool, +1. $\endgroup$ Commented Mar 1, 2013 at 17:36
  • $\begingroup$ @Leonid I had no idea this was esoteric. :-) $\endgroup$
    – Mr.Wizard
    Commented Mar 1, 2013 at 17:39
  • $\begingroup$ This particular form is not documented (list of functions inside OptionsPattern[]). I wasn't aware of it. $\endgroup$ Commented Mar 1, 2013 at 17:49
  • $\begingroup$ @Leonid I put a copy of a line from the documentation at the top of my post. Does it not describe this use? $\endgroup$
    – Mr.Wizard
    Commented Mar 1, 2013 at 18:10
  • 1
    $\begingroup$ @Santi (1) To escape code that includes a back-tick you must wrap it in double back-ticks. (2) I suggest you post a new question with a minimal working example of both packages A and B. To debug the problem I would need to start by recreating these myself and it would be better that it come from you so that it is genuinely representative. $\endgroup$
    – Mr.Wizard
    Commented Mar 16, 2015 at 23:04
6
$\begingroup$

The problem in this particular case comes from the default setting of the Dividers option, which overrides the Frame option settings. This does not strike me as a right behavior, or at least these options are not as orthogonal as they should be. This appears to fix the problem:

Options[myGrid] = 
   Join[{Frame -> All, "Tooltip" -> False}, 
      DeleteCases[Options[Grid], Dividers -> _]];

On a general note, however, I would add all options you may ever want to pass to some functions inside your function, explicitly as valid options of your function. If you find this too bothersome, you can, for this particular function (myGrid), switch back to good old OptionQ pattern:

myGrid[content_, opts___?OptionQ] := ...

at the expense of the short "magical" version of OptionValue not working any more, so you will have to use OptionValue[myGrid,{opts},"Tooltip"]. I do this sometimes, in exactly this sort of situations.

$\endgroup$
2
  • $\begingroup$ Any advantage of using OptionQ versus OptionsPattern[] if in any case you will end up using the longer versions of OptionValue? $\endgroup$
    – Rojo
    Commented Mar 1, 2013 at 17:03
  • $\begingroup$ @Rojo with my method you do not need the longer version of OptionValue. $\endgroup$
    – Mr.Wizard
    Commented Mar 1, 2013 at 17:18

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.