12
$\begingroup$

Suppose I work for organisation PQR, and have been developing a suite of packages, PQRUtilities, PQRVisualization etc, all of which are neatly arranged in a context PQR. They can all then be loaded with a single package call Get["PQR`"].

The only content of the PQR package is

BeginPackage["PQR`" ,{"PQR`PQRVisualization`","PQR`PQRUtilities`"}]
(* Exported symbols added here with SymbolName::usage - but nothing here *)    
Begin["`Private`"]
(* Implementation of the package - nothing here either*)  
End[]    
EndPackage[]

I have noticed that if I call the subsidiary packages directly with Get["PQR`PQRVisualization``"] or the Needs equivalent, I get predictive code completion pop-ups including my custom functions.

However, if I just call Get["PQR`"], my functions are loaded but I do not get the nice predictive code completion.

Ultimately all these packages will be put in the Autoload part of the path, so maybe this doesn't matter. I would like to be able to provide the simpler way to load all the custom packages I've developed, and still enjoy the benefits of the code-completion suggestions. Some of my function names are quite long, e.g. PQRScatterGraph.

Is there a way I can get functions from packages loaded in this way to be visible to the code completion functionality?

$\endgroup$
4
  • $\begingroup$ Verbeia wrote: if I call the subsidiary packages directly with Needs equivalent, I get predictive code completion pop-ups including my custom functions. ............................ BUT (a) does the little drop down triangle appear that autocompletes WITH the function arguments?? and (b) if you click on the little HELP button on the RHS (which is meant to open the Help page for that function), does that work? Because neither (a) nor (b) are working for me for third party packages. I reported this to Wolfram, and got back a reply saying it was a bug re (b). I didn't report issue (a). $\endgroup$
    – wolfies
    Commented May 2, 2013 at 13:17
  • $\begingroup$ @wolfies I can't answer this as I haven't yet written the function help pages. $\endgroup$
    – Verbeia
    Commented May 2, 2013 at 13:33
  • $\begingroup$ @wolfies - I just checked, and after implementing halirutan's solution, yes, both (a) and (b) work for my custom functions. Well, I get a "file not found" error when I try to open documentation pages that don't exist, but it works other than that :) $\endgroup$
    – Verbeia
    Commented May 2, 2013 at 23:13
  • 1
    $\begingroup$ Symbols buried deep in contexts (e.g. a`b`c) don't auto-complete. I suggested to support that this would be nice to have. If you also do, maybe they'll implement it. $\endgroup$
    – Szabolcs
    Commented May 2, 2013 at 23:48

1 Answer 1

11
$\begingroup$

In your situation, the standard approach is usually different. This means, I use something like this only

BeginPackage["PQR`" ,{"PQR`PQRVisualization`","PQR`PQRUtilities`"}]

when I need the functionality of the Visualization and Utilities inside my package, not to re-export them. What about creating an directory structure the following way

PQR
├── Kernel
│   └── init.m
├── PQRUtilities.m
└── PQRVisualization.m

And in the init.m you Get your sub-packages. Placing this in folder which Mathematica can find lets you <<PQR` and everything should work as expected.


Update: If you want to have an example where such approach is used, then look at $InstallationDirectory/AddOns/Packages/BarCharts. You load <<BarCharts`, but there is no package BarCharts.m, it's only a collection of different sub-packages which are loaded through the init.m

BarCharts/
├── Charts.m
├── Charts3D.m
├── Kernel
│   └── init.m
├── PacletInfo.m
└── Usage.m

And the Kernel/init.m contains

Get["BarCharts`Usage`"];
Get["BarCharts`Charts`"];
Get["BarCharts`Charts3D`"];

There was a follow-up question from Verbeia in the comments:

This works great, thanks! But one quick question - is there a reason why it works for Get and gives an error Needs::nocont: Context PQR` was not created when Needs was evaluated. >> when using Needs

Yes, the reason is that Needs["PQR`"] expects that a context PQR` is actually created which is not the case if it is really just a dummy directory/package. This means,

  • when you set up the structure like I described
  • and there is no .m file which is named after the parent package directory PQR
  • and every sub-package only creates its own context by calling BeginPackage["PQR`Sub`"]

then you get this warning when you call Needs["PQR`"].

If you inspect now the BarCharts example in more detail, you see that they, although using different file names, always use BeginPackage["BarCharts`"] and therefore introduce there different functions in the same namespace/context. The question is here, what you want to achieve with your package structure, because after loading your package all exported functions are visible without you noticing they are in different sub-packages/contexts.

What I usually do is the following: When my packages contain several sub-packages, then there is still one main-package which provides core functionality. To give an specific example: An image processing package IP could provide basic functions under IP/IP.m while addressing more special things in sub-packages like IP/Segmentation.m. The simplest solution for you is therefore to make a package file PQR/PQR.m which introduces the namespace/context PQR` and the message will be gone.

Note that if some subpackages use functions that are defined in other subpackages, you will need to order the calls to Get in init.m carefully.

$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.