from module - encapsulate MATLAB package into a name space module by Daniel Dolan
Modules are handy way to access packages in MATLAB.

name=module(package,mode)
% module : create a package module
%
% This function encapsulates a package directory into a module, simplifying
% function access without altering the MATLAB path.  To understand how
% modules are useful, consider the following multi-directory project.
%    ./main.m         % main routine
%    ./+GUI           % graphical user interface package (functions A, B, ...)
%    ./+GUI/+graphics % low level graphics package (functions 1, 2, ...)
% Package functions are normally accessed with a prefix:
%    [...]=GUI.functionA(...); % function A in GUI package
%    [...]=GUI.functionB(...); % function B in GUI package
%    [...]=GUI.graphics.function1(...); % function 1 in graphics sub-package
%    [...]=GUI.graphics.function2(...); % function 2 in graphics sub-package
% indicating where the function resides with respect to the top of the
% package (highest directory that starts with a '+').  Prefixes are fine
% for top-down access (though they can become quite long) and can be
% eliminated with MATLAB's "import" function, although importing a package
% can create name space confusion without warning.  The bigger problem is
% that prefixes are required for function calls at the same level.  For
% example, functionA must access functionB as 'GUI.functionB' (or import
% the GUI package); similiarly, function1 must access function2 as
% 'GUI.graphics.function2'.  This requirement makes it difficult to use
% standardized libraries in user-developed packages because intra-library
% calls must be modified manually.  Package tree revisions are particularly
% difficult, requiring manual corrections throughout the project.
%
% Modules avoid this unpleasantness by storing functions as handles inside
% a structure.  For example, the following code loads the GUI package into
% a module called 'local' for use in the main routine.
%     local=module('GUI'); % use this from functions in ./
%     [...]=local.functionA(...);
% Sub-packages can also be accessed.
%     local2=module('GUI.graphics');
%     [...]=local2.function1(...);
% Module definitions are location specific. The following code illustrates
% accessing the graphics package from inside the GUI package.
%     graphics=module('graphics'); % use this from functions in ./+GUI
%     [...]=graphics.function1(...);
% When no package is specified, the module is created where it is called.
% This permits function1 to access function2 without knowing anything about
% higher package levels.
%     name=module(); % access calling function's directory (*)
%     [...]=name.function2(...);
% This last example seems trivial, but MATLAB's implementation of packages
% breaks the traditional rule where functions can see other functions
% inside the same directory.
% (*) Modules defined without an explicit package name reference the lowest
% entry point of the package hierarchy, skipping class directories.
%
% Some upfront effort is needed to use modules, so it is recommended only
% for large projects.  Behind the scenes, modules are merely automatic
% constructions of the package prefix, and as such all features that
% support packages (such as classes) should work within modules.  Remember,
% modules are only valid as long as the top package is visible to MATLAB!
% In the preceeding examples, this means the directory containing 'main.m'
% and +GUI must be on the MATLAB path
%
% For situations where similar modules are constantly being created, such
% as graphical user interfaces, it *might* be worthwhile to create
% persistent modules:
%    function some_function(varargin)
%    persistent name
%    if isempty(name)
%       name=module;
%    end
% or use global modules where necessary (standard warnings apply).
% Finally, all calls to package functions should use parenthesis:
%    module_name.function_name(); % always use parenthesis!
% even if the underlying function has no inputs.  Omitting the parenthesis
% will return the function handle instead of evaluating the function.

% created September 3, 2012 by Daniel Dolan (Sandia National Laboratories)
function name=module(package,mode)

% handle input
if (nargin<1)
    package='';
end

if (nargin<2) || isempty(mode)
    mode='quiet';
    %mode='verbose';
end

% default output
name=struct();

% determine where module is being defined
callstack=dbstack('-completenames');
if numel(callstack)==1
    start=pwd;
else
    start=callstack(2).file;
    start=fileparts(start); % strip off function name
end

% locate top package level
root={};
while numel(start)>0
    [temp,dirname]=fileparts(start);
    if dirname(1)=='+' % package directory
        start=temp;
        root{end+1}=dirname(2:end);
    elseif dirname(1)=='@' % back out of class directories
        start=temp;
    else
        break
    end
end
root=sprintf('%s.',root{:});
package=[root package];
if isempty(package)
    error('ERROR: no package could be found');
elseif package(end)=='.'
    package=package(1:end-1);
end

% link package files to module
target=strrep(package,'.',[filesep '+']);
target=[filesep '+' target];
target=fullfile(start,target);
file=dir(target);
for n=1:numel(file)
    if file(n).isdir
        continue % ignore directories
    end
    [~,function_name,ext]=fileparts(file(n).name);
    if strcmpi(ext,'.m')  || strcmpi(ext,'.p')
        % do nothing
    else
        continue % ignore non-MATLAB files
    end
    name.(function_name)=str2func(sprintf('%s.%s',package,function_name));
end

if strcmpi(mode,'verbose')
    fprintf('Module created from the %s package, located in \n\t%s\n',...
        package,target);
end

end

Contact us