Some Matlab packages will require initialization before they’ll work, beyond just getting their M-code on the Matlab path. This could include adding Java JARs to the Matlab javaclasspath, loading native DLLs, discovering initial setting from their environment, and so on.

Matlab does not provide a mechanism for code outside Toolboxes to do load-time initialization, so MatlabProjectTemplate provides support for it using a trick that lets your library auto-initialize, with nothing required from your users besides getting your Mcode/ on their path. It does require some work on your part, though.

The trick

The trick is to use Constant class properties, object inheritance, and a couple initialization functions together to make the initializer code run whenever your code is used.

Here’s how to do the trick:

Define an initializePackage function that does the low-level initialization (like path and javaclasspath setting). It must be coded with no dependencies on any of your package’s other code. This function will run once at package startup. Have it set an appdata to indicate that it has run, and short-circuit if it’s called again after that initial call.

Define a LibraryInitializer class that calls your initializePackage() in its constructor.

Define MyPackageBase and MyPackageBaseHandle classes that will be base classes for all the other classes in your package. MyPackageBaseHandle inherits from handle; MyPackageBase does not. Both of them create a LibraryInitializer using Constant properties:

  properties (Constant, Hidden)
    initializer = mycoolpackage.internal.LibraryInitializer;
  end

Then have all the other code in your package which depends on library initialization be implemented in classes which inherit, either directly or indirectly, from MyPackageBase or MyPackageBaseHandle.

If you supply functions as part of your package, they need to be written as wrappers that call static methods on classes that inherit from MyPackageBase(Handle), and have the actual implementation code live in those static methods.

Then, define a globals class and a Settings class. The Settings class holds all your package-wide run-time settings, and must inherit from handle. Define a static Settings.discover() method which discovers your default settings from the environment. And then add this to globals:

  properties (Constant)
    % Global settings for mycoolpackage.
    settings = mycoolpackage.Settings.discover
  end

We split this discovery stuff out from the low-level initialization in initializePackage so that your package can survive a clear classes and automatically rediscover its default settings after clear classes happens. The initializePackage code only runs once at package first use time; the Settings code needs to run again automatically each time a clear classes happens.

All this code should go in your +internal subpackage, except for globals and Settings, which go in your top-level package, because those are user-visible.

Sheesh, that’s a lot!

Yep. Sorry. But I haven’t come up with a better way of doing it yet.

Toolboxes

This isn’t needed for Matlab Toolboxes, because they have hooks for startup code to run when the Toolbox is loaded. But you don’t want your code to run only as a Toolbox, do you? That would mean you needed to do a build and install step every time you changed your code and wanted to test it out! Because Toolboxes require build and installation, and Matlab doesn’t have virtual environment support, they’re not really suitable for use by developers. So use this auto-initialization trick instead of Toolbox startup code.

Acknowledgments

Thanks to David for helping me come up with this trick!