5
$\begingroup$

I am trying to define two different packages that process some information in a different way. These packages have functions into them with optional arguments. The names of the optional arguments happen to collide and Mathematica is complaining about shadowing of these symbols. Here is an example of my code:

BeginPackage["MyPackage1`"]
Options[f] = {a -> 1, b -> 2};
f[OptionsPattern[]] := {OptionValue[a], OptionValue[b]};
EndPackage[]

BeginPackage["MyPackage2`"]
Options[g] = {a -> 1, b -> 2};
g[OptionsPattern[]] := {OptionValue[a], OptionValue[b]};
EndPackage[]

Mathematica complains:

"Symbol "a" appears in multiple contexts ({"MyPackage2`", "MyPackage1`"}); definitions in context "MyPackage2`" may shadow or be shadowed by other definitions."

Now I try:

Needs["MyPackage1`"]
Needs["MyPackage2`"]
f[a -> 3, b -> 4]
g[a -> 1, b -> 2]
(* {3,4}  {1,2} *)

Thus, the functions work correctly as they are supposed to, but Mathematica is insisting on coloring a and b in red everywhere and that they appear in different contexts.

Is there a way to solve this problem? (without renaming a and b as they represent the same input data in the two packages, would be non-intuitive to change their names).

$\endgroup$
  • 4
    $\begingroup$ The strategy done by the built-in packages was to declare symbols common to both packages in a Common` context. $\endgroup$ – J. M. is away May 29 '15 at 3:34
  • $\begingroup$ For private options you can also use strings. $\endgroup$ – FJRA May 29 '15 at 3:42
  • 1
    $\begingroup$ @FJRA, if you'll indulge me a rant: one peeve I've always had since Mathematica started using strings for options was that one cannot attach usage messages to strings, and thus one cannot use ? to learn more about them without having to refer to the docs. $\endgroup$ – J. M. is away May 29 '15 at 3:51
  • $\begingroup$ @Guesswhoitis. that's indeed a very good point. Anyway in private functions (if I ever document them :) ), I include the options in the main usage message of the function, and not on each option. But in bigger projects the usage of a Common context is many times necessary. $\endgroup$ – FJRA May 29 '15 at 3:57
  • $\begingroup$ Thanks guys. @Guesswhoitis., So, I should add an extra BeginPackage and name the context common` for example. But then, how do I refer to the symbols in the arguments? Common` even in the function options definition? Or just use them directly? Thanks! $\endgroup$ – Bichoy May 29 '15 at 4:09
4
$\begingroup$

Guided by Guess who it is comments, I managed to do it. The solution as suggested by his comments is to define a common package say MyCommon` to declare the symbols and both MyPackage1` and MyPackage2` should use Needs[MyCommon`] to get the symbols. Also as he mentioned, this allows for documenting the symbols as well.

Here is my current implementation to solve the problem:

(* Package MyCommon` *)
BeginPackage["MyCommon`"]
If [ Not @ ValueQ[a::usage], a::usage = "This is a" ];
If [ Not @ ValueQ[b::usage], b::usage = "This is b" ];
EndPackage[]

(* Package MyPackage1` *)
BeginPackage["MyPackage1`", "MyCommon`"] (* MyCommon` passed as Needs *)
Options[f] = {a -> 1, b -> 2};
f[OptionsPattern[]] := {OptionValue[a], OptionValue[b]};
EndPackage[]

(* Package MyPackage2` *)
BeginPackage["MyPackage2`", "MyCommon`"] (* MyCommon` passed as Needs *)
Options[g] = {a -> 1, b -> 2};
g[OptionsPattern[]] := {OptionValue[a], OptionValue[b]};
EndPackage[]

Now, testing this implementation:

Needs["MyPackage1`"]
Needs["MyPackage2`"]
f[a -> 3, b -> 4]
g[a -> 1, b -> 2]
(*{3,4} {1,2}*)

which works without any complaints about the shadowing of the optional arguments symbols.

$\endgroup$
  • $\begingroup$ Nicely done. :) $\endgroup$ – J. M. is away May 29 '15 at 6:04
  • $\begingroup$ @Guesswhoitis & Bichoy I'm not sure what is the real context but including all usage or just symbol names in one additional package, for packages which are separate, just for purpose of not shadowing seems to be not so handy and scalable. It often happens that I miss the point of the question so tell my if I did again :) $\endgroup$ – Kuba May 29 '15 at 6:51
  • $\begingroup$ @Kuba, what would you suggest, then? $\endgroup$ – J. M. is away May 29 '15 at 7:08
  • 1
    $\begingroup$ @Kuba, if the packages are meant to be completely independent, maybe, so you replace the annoyance of undocumentable strings with long-ish usage messages for the function proper. But for closely-related packages, a Common.m package looks more attractive to me. $\endgroup$ – J. M. is away May 29 '15 at 7:22
  • 1
    $\begingroup$ @Guesswhoitis. Notice that the fact those may be closely related packages does not mean the same option will do the same thing in both packages. So different usage names are desired. Still depends of the context of course. Maybe it's just a matter of taste, but I think it is good to leave those comments here as on topic. $\endgroup$ – Kuba May 29 '15 at 7:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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