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$
9
  • 4
    $\begingroup$ The strategy done by the built-in packages was to declare symbols common to both packages in a Common` context. $\endgroup$ Commented May 29, 2015 at 3:34
  • $\begingroup$ For private options you can also use strings. $\endgroup$
    – FJRA
    Commented May 29, 2015 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$ Commented May 29, 2015 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
    Commented May 29, 2015 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
    Commented May 29, 2015 at 4:09

1 Answer 1

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$
8
  • $\begingroup$ Nicely done. :) $\endgroup$ Commented May 29, 2015 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
    Commented May 29, 2015 at 6:51
  • $\begingroup$ @Kuba, what would you suggest, then? $\endgroup$ Commented May 29, 2015 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$ Commented May 29, 2015 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
    Commented May 29, 2015 at 7:27

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.