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.

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.

share|improve this question

2 Answers 2

up vote 10 down vote accepted

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.

share|improve this answer
    
This is pretty cool, +1. –  Leonid Shifrin Mar 1 '13 at 17:36
    
@Leonid I had no idea this was esoteric. :-) –  Mr.Wizard Mar 1 '13 at 17:39
    
This particular form is not documented (list of functions inside OptionsPattern[]). I wasn't aware of it. –  Leonid Shifrin Mar 1 '13 at 17:49
    
@Leonid I put a copy of a line from the documentation at the top of my post. Does it not describe this use? –  Mr.Wizard Mar 1 '13 at 18:10
    
This does indeed, but this is not what I see in the V9 documentation‌​, where only list of rules is mentioned. I will try to remember to ask why there was such a change. –  Leonid Shifrin Mar 1 '13 at 19:30

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.

share|improve this answer
    
Any advantage of using OptionQ versus OptionsPattern[] if in any case you will end up using the longer versions of OptionValue? –  Rojo Mar 1 '13 at 17:03
    
@Rojo with my method you do not need the longer version of OptionValue. –  Mr.Wizard Mar 1 '13 at 17:18

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.