Mathematica: GOTCHA: Package usages (Needs) are not transitive

Icon class
icon_class
far fa-sticky-note
icon_class_computed
far fa-sticky-note
Note kind
Webel IT Australia promotes the amazing Mathematica tool and the powerful Wolfram Language and offers professional Mathematica services for computational computing and data analysis. Our Mathematica tips, issue tracking, and wishlist is offered here most constructively to help improve the tool and language and support the Mathematica user community.
DISCLAIMER: Wolfram Research does not officially endorse analysis by Webel IT Australia.
Keywords
Click on the image to view it full size

If a Package TestC has a usage (Needs) declaration for Package TestB (only), and Package TestB has a usage declaration for TestA, the Package TestC will NOT automatically (transitively) see public expressions in Package TestA.

There may be good reasons for this in the Wolfram Language, but it's slightly annoying, as it makes managing Package dependencies harder (compare with the Eclipse IDE transitive Plugin system).

Example: We want to reuse functions from TestA:


BeginPackage["TestA`"]

fInA::usage = "finA[x]";

Begin["`Private`"]  

fInA[x_] := x^2;

End[]

EndPackage[]

Package TestB declares a usage (Needs):


BeginPackage["TestB`", { "TestA`"}]

fInB::usage = "finB[x] Relies on A using direct package usage";

Begin["`Private`"]

fInB[x_] := 2 fInA[x];

End[]

EndPackage[]

Package TestC "tries" to get at TestA via TestB:


BeginPackage["TestC`", { "TestB`"}]

fInCvsB::usage = "fInCvsB[x] Relies on direct package usage.";

fInCvsA::usage = "fInCvsA[x] Relies on TestB to load TestA: FAILS!";

fInCvsAdir::usage = "fInCvsAdir[x] Uses explicit namespace-qualified access ";

Begin["`Private`"]

fInCvsB[x_] := 4 fInB[x];

fInCvsA[x_] := 4 fInA[x];

fInCvsAdir[x_] := 4 TestA`fInA[x];

End[]

EndPackage[]
Here the access to TestB from TestC works fine:

fInCvsB[2]

32
But accessing TestA indirectly FAILS:

fInCvsA[2]

4 TestC`Private`fInA[2]
One can, however, access the public functions of TestA from TestC using namespace qualifiers:

fInCvsAdir[2]

16
To access without such qualifiers you need an explicit usage of TestA in TestC:

BeginPackage["TestC`", { "TestA`", "TestB`"}]
The Systems Modeling Language (SysML®) image represents the Package dependencies (Needs) as SysML Usages and the function Dependencies.
Relates to
Related notes
Related notes (backlinks)
Related snippets (extracts)
Visit also
Visit also (backlinks)