I'm building a Mathematica application "APPStestI" that contains three packages: SUBappsA.m, SUBappsB.m, SUBappsC.m and APPStestI.m. Where APPStestI.m is the main package; SUBappsA.m and SUBappsB.m contains some functions and SUBappsC.m stores the values of the constants used by other packages.

init.m

Get[ "APPStestIAPPStestI"]
Get[ "APPStestISUBappsA"]
Get[ "APPStestISUBappsB"]
Get[ "APPStestISUBappsC"]


APPStestI.m

BeginPackage["APPStestI"]

Print [Style[" Mathematica application ","Text"]];

EndPackage[]


SUBappsA.m

In this package we use the stored value of x.

BeginPackage["APPStestISUBappsA"]

Get[ "APPStestISUBappsC"]
Unprotect["SUBappsA*"];
ClearAll["SUBappsA*"];

funI::usage = "funI[ x]"

Begin["Private"] (* Begin Private Context *)

funI[xp_] := Module[ {yp}, yp = xp^2+x; yp + 1 ]

End[] (* End Private Context *)

Protect["SUBappsA*"];

EndPackage[]


SUBappsB.m

In this package we use the stored value of WW.

BeginPackage["APPStestISUBappsB"]

Get[ "APPStestISUBappsA"]
Get[ "APPStestISUBappsC"]
Unprotect["SUBappsB*"];
ClearAll["SUBappsB*"];

funII::usage = "funII[w] computes a simple function."

Begin["Private"]

funII[ wp_] := Module[ {zp}, zp = wp^3+ funI[WW]; zp + 1]

End[]

Protect["SUBappsB*"];

EndPackage[]


SUBappsC.m

BeginPackage["APPStestISUBappsC"]

Unprotect["SUBappsC*"];
ClearAll["SUBappsC*"];

y::usage= "5"
WW::usage= "10"
x::usage= "3"
z::usage= "4"

Begin["Private"]

{  y = 5,  WW = 10,  x = 3,  z = 4 };

End[]

Protect["SUBappsC*"];

EndPackage[]


<< APPStestI


z::shdw: Symbol z appears in multiple contexts {APPStestISUBappsC,Global}; definitions in context APPStestISUBappsC may shadow or be shadowed by other definitions.

The application performs the operations correctly, but I can not solve this problem.

Minor issues:

• Get always loads while Needs only if needed so if someone calls your init.m file then SUBappsC.m will be loaded 3 times. You probablt don't want that.

• Unprotect["SUBappsB*"] - this and friends won't do anything because this context does not exist at all.

The main problem is that your SUBappsC.m creates x, y, z, WW in APPStestISUBappsC which is one of exported contexts. (It will appear on a $ContextPath after EndPackage[]. Packages should not export dummy variables because of collisions/shadowing problems. That is why Begin["Private"] is used. You however need to share them as they are not just dummy variables. (giving them more meanigful names would be a good idea if they are meant to float around your implementation files) The common approach to creating symbols which are shared between implementation files but not outside is to use an additional context that is invoked in each file. Let me show you a problematic code and a proposed solution: Remove[z]; (*or restart the kernel*) z = 1; (*again global*)   (*First package*) BeginPackage["MyPackage1"]; BeginPackage["Common"]; z::usage = "here's z from MyPackage1Common"; (*symbols exported to a shared context*) EndPackage[]; Begin["Private"]; (*whatever*) End[]; EndPackage[];   (*And in anotherpackage:*) BeginPackage["MyPackage2"]; (*I would use the same MyPackage1 across many subpackages unless there is a reason not to. Here I created another context just to show that it won't break our scheme*) Needs @ "MyPackage1"; (*adds it to a$ContextPath, nothing there anyway*)
Needs @ "MyPackage1Common"; (*z's here*)

Begin["Private"];
Print[z::usage] (*could it work? yep*)
End[];

EndPackage[];


As I said, I'd not use so many different nested context but maybe you have a good reason to do so. Then you need to be in control.

• Does anyone ever -- or rather is it advisable to treat a package like a class object (in OO programming) and make package parameters private but accessible only through methods? E.g. getParam["x"], setParam["x", 3], etc. It also allows one to validate assignments and maintain dependencies. (This seemed to be a common style in Obj-C, AFAIR. But my days of serious programming are long gone.) Commented Jan 25, 2019 at 12:40
• @MichaelE2 I think b3m2a1 does a lot of related stuff and can say more. I'd say it makes sense if you have a strong background in OOP. I don't and it was always a pain for me, and not very idiomatic. Moreover I mostly deal with GUI and I need a flexible access to symbols for Dynamic` purposes, so I don't have time to set all needed methods.