I'm trying to define a function that is evaluated differently depending on its options. This code
Options[Foo]={Bar->True}; Foo[a_,b_, OptionsPattern[]]:= A /; OptionValue[Bar]; Foo[a_,b_, OptionsPattern[]]:= B /; !OptionValue[Bar]; works as expected. Evaluating
{Foo[x,y,Bar->True], Foo[x,y,Bar->False], SetOptions[Foo,Bar->True]; Foo[x,y,Bar->True], Foo[x,y,Bar->False], SetOptions[Foo,Bar->False]; Foo[x,y,{Bar->True}], Foo[x,y,{Bar->False}], SetOptions[Foo,Bar->True]; Foo[x,y], SetOptions[Foo,Bar->False]; Foo[x,y]} I get
{A, B, A, B, A, B, A, B} which is precisely what I want. However, if I try to make b a blank sequence, i.e.
Options[Foo]={Bar->True}; Foo[a_,b__, OptionsPattern[]]:= A /; OptionValue[Bar]; Foo[a_,b__, OptionsPattern[]]:= B /; !OptionValue[Bar]; weird things start happening. Evaluating my second code sample I get
{A, B, A, A, A, B, A, B} which is obviously wrong. A possible workaround is to write
Options[Foo]={Bar->True}; Foo[a_,b__/;FreeQ[{b},Rule], OptionsPattern[]]:= A /; OptionValue[Bar]; Foo[a_,b__/;FreeQ[{b},Rule], OptionsPattern[]]:= B /; !OptionValue[Bar]; However this doesn't seem right to me, since it's actually the job of OptionsPattern to fish out the options from my functions. Of course I could also write
Options[Foo]={Bar->True}; Foo[a_,b__, OptionsPattern[]]:= If[OptionValue[Bar],A,B] which works as well, but this is still another workaround. Moreover, if I want to have something like (in addition to the regular function definition)
Options[Foo]={Bar->True}; Foo[a_,a_,c___, OptionsPattern[]]:= 0 /; OptionValue[Bar]; then running
{Foo[x,x,Bar->True], Foo[x,x,Bar->False], SetOptions[Foo,Bar->True]; Foo[x,x,Bar->True], Foo[x,x,Bar->False], SetOptions[Foo,Bar->False]; Foo[x,x,{Bar->True}], Foo[x,x,{Bar->False}], SetOptions[Foo,Bar->True]; Foo[x,x], SetOptions[Foo,Bar->False]; Foo[x,x]} again produces wrong results
{0, Foo[x, x, Bar -> False], 0, 0, 0, Foo[x, x, {Bar -> False}], 0, Foo[x, x]} and my only solution is to use
Options[Foo]={Bar->True}; Foo[a_,a_,c___/;FreeQ[{c},Rule], OptionsPattern[]]:= 0 /; OptionValue[Bar]; which is kind of a hack.
So my question is, why using conditions with OptionValue and OptionsPattern works if the last pattern before OptionsPattern is a blank, but fails if it is a blank sequence. Is it a bug, or am I missing something essential about OptionsPattern?
I'm observing this behavior both on Mathematca 9.0.1 and Mathematica 10.0.1 under Linux.
Options[Foo] = {Bar -> True}; Foo[a_, b___, c_ /; ! OptionQ[c], OptionsPattern[]] := A /; OptionValue[Bar]; Foo[a_, b___, c_ /; ! OptionQ[c], OptionsPattern[]] := B /; ! OptionValue[Bar];$\endgroup$