I have a directory with some helper functions that should be put into a package. Step one is obviously naming the directory something like +mypackage\
so I can call functions with mypackage.somefunction
. The problem is, some functions depend on one another, and apparently MATLAB requires package functions to call functions in the very same package still by explicitly stating the package name, so I'd have to rewrite all function calls. Even worse, should I decide to rename the package, all function calls would have to be rewritten as well. These functions don't even work correctly anymore when I cd
into the directory as soon as its name starts with a +
.
Is there an easier solution than rewriting a lot? Or at least something self-referential like import this.*
to facilitate future package renaming?
edit I noticed the same goes for classes and static methods, which is why I put the self-referential part into this separate question.
I have been exploring answers to the same question and I have found that combining package with private folders can allow most or all of the code to be used without modification.
Say you have
Then from
intfc1
,foo1
,foo2
, andfoo3
are all reachable without any package qualifiers or import statements, andfoo1
,foo2
, andfoo3
can also call each other without any package qualifiers or import statements. Iffoo1
,foo2
, orfoo3
needs to callintfc1
orintfc2
, then that needs qualification asmypackage.intfc1
or an import statement.In the case that you have a large set of mutually interdependent functions and a small number of entry points, this reduces the burden of adding qualifiers or import statements.
To go even further, you could create new wrapper functions at the package level with the same name as private functions
where for example
+mypackage\foo1.m
might be:This way, unlike the
intfc1
example above, all the private code can run without modification. In particular there is no need for package qualifiers when calling any other function, regardless of whether it is exposed by a wrapper at the package level.With this configuration, all functions including the package-level wrappers are oblivious of the package name, so renaming the package is nothing more than renaming the folder.
In truth, I don't know that you should really be renaming your packages often. It seems to me that the whole idea behind a package in MATLAB is to organize a set of related functions and classes into a single collection that you could easily use or distribute as a "toolbox" without having to worry about name collisions.
As such, placing functions and classes into packages is like a final step that you perform to make a nice polished collection of tools, so you really shouldn't have much reason to rename your packages. Furthermore, you should only have to go through once prepending the package name to package function calls.
... (pausing to think if what I'm about to suggest is a good idea ;) ) ...
However, if you really want to avoid having to go through your package and prepend your function calls with a new package name, one approach would be to use the function
mfilename
to get the full file path for the currently running package function, parse the path string to find the parent package directories (which start with "+"), then pass the result to theimport
function to import the parent packages. You could even place these steps in a separate functionpackagename
(requiring that you also use the functionevalin
):And you could then place this at the very beginning of your package functions to automatically have them include their parent package namespace:
Is this a good idea? Well, I'm not sure what the computational impacts will be if you're doing this every time you call a package function. Also, if you have packages nested within packages you will get output from
packagename
that looks like this:And the call to
import
will only include the immediate parent packagesubsubpack
. If you also want to include the other parent packages, you would have to sequentially remove the last package from the above string and import the remainder of the string.In short, this isn't a very clean solution, but it is possible to make your package a little easier to rename in this way. However, I would still suggest that it's better to view the creation of a package as a final step in the process of creating a core set of tools, in which case renaming should be an unlikely scenario and prepending package function calls with the package name would only have to be done once.