6

Could a package be composed of references (e.g. usage messages)? Do the code for an induvidual function implemented in a package has to be physically in that package file where it is referenced (i.e. externalized)?

Or can the actual function code be referenced in one package and located somewhere in another notebook?

István Zachar
  • 47,032
  • 20
  • 143
  • 291

1 Answers1

8

Yes. Actually, if I recall correctly, there were packages supplied with earlier versions of Mathematica which came with a common.m (or usage.m) package file that only contained the usage messages, but not the function definitions which were stored in other package files usually at the same directory (or subdirectory).

Directory structure

To set up such a distributed package, create the home directory myPackage for the files (preferably somewhere in your defined $Path). The directory structure should look like this:

.../myPackage/Kernel/init.m
    myPackage/common.m
    myPackage/firstFile.m
    myPackage/nextFile.m
    ...

Kernel initialization file

You have to have a Kernel subdirectory (next to your package files), with an init.m with the following content:

Get["myPackage`common`"];
Get["myPackage`firstFile`"];
Get["myPackage`nextFile`"];
(* include any forther package files similarly with Get *)

Common usage message file

Your common.m file should look like this (note that you can name this file anything, common or usage are just conventions):

BeginPackage["myPackage`"]; 
  function1::usage = "This is the usage message of function1.";
  function2::usage = "This is the usage message of function2.";
  functionInNextFile::usage = "This is the usage message of functionInNextFile.";
  (* further usage messages *)
EndPackage[];

Note, that while we intentionally separate function from usage message, one can still include function definitions in the common.m file.

Function definitions file

Let's assume you have subpackage files with names e.g. firstFile.m, nextFile.m, etc. storing function definitions. These files should also start with BeginPackage["myPackage`"], and should comply with the following structure (given for firstFile.m):

BeginPackage["myPackage`"];
  (* List usage messages of the functions that were not listed in common.m *)
  function0::usage = "function0 was not included in common.m.";
  Begin["`Private`"];
    (* Function definitions *)
    function0[] := 0;
    function1[] := 1;
    function2[] := {2, functionInNextFile[]};
  End[];
  Protect[function0, function1, function2]; 
EndPackage[];

Note that you can even reference other functions defined in other files (e.g. functionInNextFile). For sake of completeness, here are the contents of nextFile.m:

BeginPackage["myPackage`"];
  Begin["`Private`"];
    functionInNextFile[] := 4
  End[];
  Protect[functionInNextFile]; 
EndPackage[];

Testing

Now one can simply call the package from Mathematica the usual way, and test whether usage messages and functions were externalized (i.e. made public) correctly:

Needs["myPackage`"]
function1::usage
function0[]
function1[]
function2[]
functionInNextFile[]
This is the usage message of function1.
0
1
{2, 4}
4
István Zachar
  • 47,032
  • 20
  • 143
  • 291
  • Do you have some more information?. . .I tried with a masterPackage containing the usage messages. . . And a f1Package and a f2Package containing the definitions of two functions. . .I can not reach the functions in f1package and f2Packege from a notebook where the masterPackage is loaded. . .All are in the same directory. . .No error is displayed. . .f11[1, 2] just respons with f11[1, 2]. – Hp Radojewski Schäfer Von Apr 02 '13 at 11:42
  • @HpRadojewskiSchäferVon take a look at the Histograms` package in v.8. It is built out of several .m files, one of which is Usage.m. The key is that contexts are not closed, and may be added to as you wish. – rcollyer Apr 02 '13 at 14:02
  • @rcollyer What do you mean by "contexts are not closed"? This is a bit confusing as every file has an EndPackage statement at the end. Could you please explain it? – István Zachar Apr 02 '13 at 14:12
  • The primary purpose of EndPackage is to reset the original $ContextPath. You can always add new symbols to a context either by using Begin/End, or BeginPackage/EndPackage, or even SomeContext`newSymbol = .... So, they act a lot like a namespace in c++ which is not closed to additional "symbols", unlike a c++ class which is closed. – rcollyer Apr 02 '13 at 14:34
  • Istvan, could you please try to give a complete simple working example encluding the last step where we call one of the defined functions? – Hp Radojewski Schäfer Von Apr 07 '13 at 21:10
  • @HpR Please see edit. If you still have questions or it does not do what you expect, don't hesitate to ask! – István Zachar Apr 10 '13 at 16:49
  • I appreciate your effords. . .The result so far when calling from a notebook: SetDirectory["F:\\LargeDataSet\\Programme\\myPackage"];
    NotebookDirectory[]
    "F:\LargeDataSet\Programme\"
    . . .Needs["myPackage´"];
    Get::noopen: "Cannot open myPackage´"
    Needs::nocont: "Context myPackage´ was not created when Needs was evaluated."
    . . . Note I used the "´" instead of "`" just to bring it inside this example here.
    – Hp Radojewski Schäfer Von Apr 12 '13 at 09:22
  • @HPR Did you set all cells in all the package files to be initialization cells (right click on cell bracket)? – István Zachar Apr 12 '13 at 09:45
  • OK. . .You are right. . .What is the possible use of not including function0 in common.m? – Hp Radojewski Schäfer Von Apr 13 '13 at 17:15
  • @HpR I don't think there is any drawback, sometimes it is more convenient to include the usage next to the functions, especially during development, to easily update usage when the function signature changes. – István Zachar Apr 14 '13 at 10:31
  • OK. . I see. . .Now we can show whats in myPackage, – Hp Radojewski Schäfer Von Apr 14 '13 at 11:09
  • OK. . I see. . .Now we can show what's in myPackage, . . .?"myPackage`*". . .And we can show what's in the folder of myPackage, . . .FileNames[]. . .Can we show which of the defined functions is in which package? – Hp Radojewski Schäfer Von Apr 14 '13 at 11:15
  • @HpR I don't think so, as practically all these package files count as one package: they inject their symbols in the same myPackage context and that is the only thing that matters for Mathematica when it calls the package with Needs. – István Zachar Apr 14 '13 at 13:30