Group Abstract Group Abstract

Message Boards Message Boards

5
|
9.7K Views
|
8 Replies
|
19 Total Likes
View groups...
Share
Share this post:

How to setup and organize larger paclets as of v13+

8 Replies
POSTED BY: Bob Sandheinrich

Using Get puts contexts on $ContextPath

Using Get or Needs in the private portion of a package does not pollute the user's context path:

In[5]:= cpath = $ContextPath;
In[6]:= Needs["PublisherID`PacletName`"];
In[7]:= Complement[$ContextPath, cpath]

Out[7]= {"PublisherID`PacletName`"}
POSTED BY: Jason Biggs

I get an error when loading the paclet using the structure you've laid out, the line

Needs["PublisherID`PacletName`Core`" -> None]

because the package can't be found

In[3]:= FindFile["PublisherID`PacletName`Core`"]
Out[3]= $Failed

If I modify the kernel extension in the paclet info file to use

"Context" -> {
    {"PublisherID`PacletName`", "PacletName.wl"},
    {"PublisherID`PacletName`Core`", "Core.wl"},
    {"PublisherID`PacletName`Special`", "Special.wl"}
}

then it works as you describe.

I don't know if the method I lay out below is the 'best' practice but it works for me. I added another .wl file with package-internal functions that can be used by other subpackages that aren't exported to the user.

PacletName.wl

BeginPackage["PublisherID`PacletName`"]

(* implemented in Core.wl *)
coreFunc::usage = "..."

(* implemented in Special.wl *)
specialFunc::usage = "..."

Begin["`Private`"]

(* load all sub-packages here in the private context *)
Get["PublisherID`PacletName`Internal`"]
Get["PublisherID`PacletName`Core`"]
Get["PublisherID`PacletName`Special`"]

End[]

EndPackage[]

Core.wl

BeginPackage["PublisherID`PacletName`Core`"]
(* Exported symbols added here with SymbolName::usage *)

Begin["`Private`"]
Needs["PublisherID`PacletName`"] (* so that coreFunc is on the context path *)

coreFunc[k : (_Integer | _List)] := 2 * k (* simple example *)

End[]
EndPackage[]

Special.wl

BeginPackage["PublisherID`PacletName`Special`"]
Begin["`Private`"]

Needs["PublisherID`PacletName`"]
Needs["PublisherID`PacletName`Internal`"] (* for helperFunc *)

specialFunc[ arg_Integer ] := coreFunc @ helperFunc @ arg

End[]
EndPackage[]

Internal.wl

BeginPackage["PublisherID`PacletName`Internal`"]
(* introduce internal symbols of the paclet *)
helperFunc::usage = "..."

Begin["`Private`"]

helperFunc[x_] := {x, x^2}

End[]
EndPackage[]

Using this structure I get the same results,

In[5]:= Needs["PublisherID`PacletName`"]

In[6]:= coreFunc[4]
Out[6]= 8

In[7]:= specialFunc[4]
Out[7]= {8, 32}

But it avoids the function aliases you are using, which I find confusing

POSTED BY: Jason Biggs

Thanks. I replied in GitHub.

POSTED BY: Bob Sandheinrich

I just tried to reproduce your sample paclet "from scratch" in Mathematica—and failed using PacletTools`CreatePaclet[]. An issue on GitHub was posted:

https://github.com/bobohilario/SampleInterdependentPaclet/issues/1#issue-2181523182

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard