Skip to main content
Add info about versions 10.2+, and paclets with different `Version`.
Source Link
jkuczm
  • 15.1k
  • 2
  • 54
  • 85

Adding directory to the beginning of the paclet search pathEdit

From version 9 PacletInfo.m file requires "Kernel" extension with Context specification. Without it loading paclets using contexts doesn't work (see old answer).

Up to version 8 $Path has precedence over paclet search path no matter how package is loaded.

In versions 9.0 - 10.1 paclet search path has precedence over $Path no matter how package is loaded.

Since version 10.2 paclet search path is used and has precedence only when package is loaded using its context. When package is loaded using file path - paclet search path is not used at all - only $Path.

As noted in comment by Kuba, since version 9, when paclet is loaded using context, always newest version (determined by Version property from PacletInfo.m) from all available on paclet search path, is loaded, regardless of order of adding directories to paclet search path. Order of adding directories to paclet search path matters only when paclets in different directories have same version, then the one from directory added later has precedence.

Old Answer

Adding directory to the beginning of the paclet search path

One thing to note is that paclet search path is used only when getting files using a path with ordinary path separator. When getting packages using path with elements separated by context separator ` paclet search path is not used.

Workaround for Workbench

Workaround for Workbench

Adding directory to the beginning of the paclet search path

One thing to note is that paclet search path is used only when getting files using a path with ordinary path separator. When getting packages using path with elements separated by context separator ` paclet search path is not used.

Workaround for Workbench

Edit

From version 9 PacletInfo.m file requires "Kernel" extension with Context specification. Without it loading paclets using contexts doesn't work (see old answer).

Up to version 8 $Path has precedence over paclet search path no matter how package is loaded.

In versions 9.0 - 10.1 paclet search path has precedence over $Path no matter how package is loaded.

Since version 10.2 paclet search path is used and has precedence only when package is loaded using its context. When package is loaded using file path - paclet search path is not used at all - only $Path.

As noted in comment by Kuba, since version 9, when paclet is loaded using context, always newest version (determined by Version property from PacletInfo.m) from all available on paclet search path, is loaded, regardless of order of adding directories to paclet search path. Order of adding directories to paclet search path matters only when paclets in different directories have same version, then the one from directory added later has precedence.

Old Answer

Adding directory to the beginning of the paclet search path

One thing to note is that paclet search path is used only when getting files using a path with ordinary path separator. When getting packages using path with elements separated by context separator ` paclet search path is not used.

Workaround for Workbench

Source Link
jkuczm
  • 15.1k
  • 2
  • 54
  • 85

Adding directory to the beginning of the paclet search path

One thing to note is that paclet search path is used only when getting files using a path with ordinary path separator. When getting packages using path with elements separated by context separator ` paclet search path is not used.

To add a directory to beginning of paclet search path in Mathematica versions 9.0 and 10.0 one can use PacletManager`PacletDirectoryAdd function.

To see how it works let's use slightly modified example from question i.e. instead of foo.txt let's use foo.m.

In Mathematica version 9 and 10 we get:

$Path = {};
Get["Test`foo`"]
(* Get::noopen: Cannot open Test`foo`. >> *)
(* $Failed *)
Get["Test/foo.m"]
(* "Applications directory" *)

(* Quit kernel *)
$Path = {$HomeDirectory};
Get["Test`foo`"]
(* "Home directory" *)
Get["Test/foo.m"]
(* "Applications directory" *)

(* Quit kernel *)
$Path = {};
PacletDirectoryAdd[$HomeDirectory];
Get["Test`foo`"]
(* Get::noopen: Cannot open Test`foo`. >> *)
(* $Failed *)
Get["Test/foo.m"]
(* "Home directory" *)

(* Quit kernel *)
$Path = {$HomeDirectory};
PacletDirectoryAdd[$HomeDirectory];
Get["Test`foo`"]
(* "Home directory" *)
Get["Test/foo.m"]
(* "Home directory" *)

So adding a directory to $Path and to paclet directories using PacletDirectoryAdd does the job and files will be always loaded from desired directory.

In Mathematica version 8 directories added with PacletDirectoryAdd are not put on the beginning of paclet search path, but it doesn't matter since in v8 ordinary $Path has precedence.

$Path = {};
Get["Test`foo`"]
(* Get::noopen: Cannot open Test`foo`. >> *)
(* $Failed *)
Get["Test/foo.m"]
(* "Applications directory" *)

(* Quit kernel *)
$Path = {$HomeDirectory};
Get["Test`foo`"]
(* "Home directory" *)
Get["Test/foo.m"]
(* "Home directory" *)

(* Quit kernel *)
$Path = {};
PacletDirectoryAdd[$HomeDirectory];
Get["Test`foo`"]
(* Get::noopen: Cannot open Test`foo`. >> *)
(* $Failed *)
Get["Test/foo.m"]
(* "Applications directory" *)

(* Quit kernel *)
$Path = {$HomeDirectory};
PacletDirectoryAdd[$HomeDirectory];
Get["Test`foo`"]
(* "Home directory" *)
Get["Test/foo.m"]
(* "Home directory" *)

Workaround for Workbench

To add elements of $Path, that are in Workbench workspace, to paclet search path one can create an init.m file with following contents:

If[$VersionNumber >= 9,
PacletManager`PacletDirectoryAdd @ Reverse @ Select[
    $Path,
        StringMatchQ[#, "/path/to/workspace/*"]&
    ]
]

Unfortunately I don't have a nice and clean method of executing this file every time it's needed.

A non-ideal solution is to start execution build command of each project with

Get["path/to/our/init.m"]