Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a directory into a package?

Tags:

package

matlab

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.

like image 317
Tobias Kienzler Avatar asked Apr 12 '11 12:04

Tobias Kienzler


1 Answers

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 the import function to import the parent packages. You could even place these steps in a separate function packagename (requiring that you also use the function evalin):

function name = packagename

  % Get full path of calling function:
  callerPath = evalin('caller', 'mfilename(''fullpath'')');

  % Parse the path string to get package directories:
  name = regexp(callerPath, '\+(\w)+', 'tokens');

  % Format the output:
  name = strcat([name{:}], [repmat({'.'}, 1, numel(name)-1) {''}]);
  name = [name{:}];

end

And you could then place this at the very beginning of your package functions to automatically have them include their parent package namespace:

import([packagename '.*']);

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:

'mainpack.subpack.subsubpack'

And the call to import will only include the immediate parent package subsubpack. 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.

like image 136
gnovice Avatar answered Sep 25 '22 17:09

gnovice