thomasloven
thomasloven

Reputation: 73

'main' function of matlab package

What I have:

I have a matlab script called myscript.m which uses the p-coded helper functions fcn_A.p and fcn_B.p (which I wrote and have the source code for).

What I want:

I'd like to distribute those to others as a single unit such that:

As far as possible, I'd also like to avoid protecting myscript. That way, it can be used as an example of how to use fcn_A and fcn_B.

Edit: Optimally, I'd like a file or folder that you just move into your path or working directory and then it all works, without even changing the path.

What I tried:

Putting everything into the same script file doesn't fulfill the second requirement.

Making it a class (either through a classdef file or a @myscript directory) doesn't fulfill the third requirement.

Making it a package (using a +myscript directory) doesn't fulfill the first requirement.

What I believe I need

I believe this could be solved if there was a way to define a 'default' function of a package. Kind of like how the contents of +mypackage/Contents.m is displayed when you type help mypackage.

Is there a way to do this?

Upvotes: 1

Views: 178

Answers (4)

thomasloven
thomasloven

Reputation: 73

It turns out that all of my requirements can in fact be fulfilled by a class by using assignin.

My solution would look like this:

Files:

@myscript
@myscript/myscript.m
@myscript/fcn_A.p
@myscript/fnc_B.p

@myscript/myscript.m

classdef myscript
  methods (Static)
    fcn_A
    fcn_B
  end
  methods
    function self = myscript()
      % Using a variable defined in the calling environment (if defined)
      outside_variable = evalin('caller', 'outside_variable', NaN);
      if isnan(outside_variable)
        outside_variable = 'default value';
      end
      ... code goes here ...
      outside_variable = self.fcn_A(parameters, outside_variable);
      % Putting the variable back in the calling environment (even if not defined before)
      assignin('caller', 'outside_variable', outside_variable);
    end
  end
end

Now:

  • Running >> myscript will run the class constructor and return an empty class object, which I can just ignore.
  • myscript.fcn_A and myscript.fcn_B can be called since they are static class functions.
  • variable_to_save will be set in the base environment as expected.
  • Moving the @myscript directory into the path at a new computer is enough to make it work.

There is one remaining problem, though. If fcn_A or fcn_B is a class, this will not work, since MATLAB doesn't allow stacked classes. Bummer! I did not mention this in the question, because I couldn't imagine it would make a difference...

Upvotes: 1

Navan
Navan

Reputation: 4477

You cannot have myscript as a script if you want a single file solution. But if the purpose of myscript is only for providing example usage and assigning output in base workspace you can achieve this using a function or class.

With a function you can put all the usage as a string and then display the string when myscript is called with no arguments or some special argument like '-help'. You can assign the outputs from myscript in the base workspace using assignin. For example,

function myscript(varargin)

if nargin == 0
 disp('Usage: myscript(fcn_a...');
 return;
end

if strcmp(varargin{1}, 'A')
  y = fcn_A(varargin{2:end});
else
  y = fcn_B(varargin{2:end});
end
assignin('base','y',y);

end

function y = fcn_A(varargin)
   y = 1;
end
function y = fcn_B(varargin)
   y = 2;
end

Now you can p-code this entire function in one file. You can do a similar setup with a class. There it might be better to show the usage using a disp method and then provide fcn_A and fcn_B as static methods of the class.

Upvotes: 1

Dennis Jaheruddin
Dennis Jaheruddin

Reputation: 21563

The way I (and mathworks) would typically do this:

  1. Make sure you have all relevant files in a folder
  2. Zip it

Now you just have 1 file for distribution, perhaps even including documentation

Note that this is actually what matlab itself does. See this link for example:

Ismemberf on matlab file exchange

Upvotes: 1

user2271770
user2271770

Reputation:

Add the folder that holds your functions and script to the MATLAB path. Fulfills all 4 conditions.

Upvotes: 1

Related Questions