Tip: calling subfunctions from outside m-file (Final)

Calling/debugging subfunctions or writing large subfunctions is straight forward with this trick.
1.1K Downloads
Updated 25 Sep 2011

View License

** Included is a skeleton file of the suggested trick. Type "myFunc" or "help myFunc" to see details shown below. **

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Bothering situations when you code in Matlab:

<< Case 1 >>

If you extensively use the Matlab, you'll soon find that your project
folder become full of small m-files. You may organize them in folders
or you may incorporate similar functionalities in an object using OOP.
However, sometimes, you just write some functions in a single m-file,
though functions other than the one at the top can be called only
within the m-file. This is perfectly fine because you usually expect
these functions never be used by other m-files.

Then, later, you find yourself wanting to access those small functions
from other m-files. Now, you need to refactor those as individual
m-files.

That's pain. You just want to use it as it is. You don't want to make
another m-file for that tiny function. Making a lot of such small
m-files turns the folder mess like a big toy box. It becomes more and
more difficult to find the one you want. You even just forget what you
have.

There are ways to avoid this pain (such as OOP as I already mentioned).
But they want to suck your attention, planning, designing and so on and
so forth. You want a real quick simple fix for it.

<< Case 2 >>

You have an m-file that includes a few subfunctions. Initially, it
was not a big deal. But as your project progress, the subfunction
itself became pretty long. Then you found something wrong with it. You
want to debug it. You mark some break points and run the top level
function of the m-file. You step into the subfunction of trouble.
You think you found something, modify a little bit, and save it, ...
which makes you get out of the current context. You need to run the
whole function from the start all again to get to that point. You don't
want to run all of the main function again just to run that sub-
function. It takes too much time and is cumbersome. You want to run it
with a simple parameter right from the command window.

Again, you decide to refactor the subfunction out of the m-file.
Afterall, it became too big to co-exist with the main function in a
single m-file. But then, it is not the only subfunction that you
need to refactor. There are lots of them. Your project folder ends up
like a trash can.

<< Case 3 >>

You want to have an m-file that has several functionalities using a
token. For example, if the token is 'A', the function do something. If
the token is 'B', the function do something else. The problem is that
'A' and 'B' requires different number of inputs/outputs. Worse, those
inputs/outputs have very different meaning. Even worse, each of 'A' and
'B' needs pretty long codes.

Natual solution for this case is to use something like 'switch'.
'switch' is a very simple good solution. But, because the meaning of
inputs/outputs are different, the code reads very confusing. If each of
'A' and 'B' requires long codes, then it is hard to find out where you
are in the 'switch' statement.

Again, refactoring each case as an individual m-file could be a good
solution. But, sometimes (not often though), you need to use the same
function name.

Solution: << My suggestion as a quick-fix >>

Let's say the name of your m-file is 'myFunc', and there are several
other subfunctions (mySub_A, mySub_B, etc) in the same m-file. Now you
want to access "mySub_A" from outside. Then do the following two steps.

1. Rename your top function (myFunc) to something else, such as
'main' or 'myFunc_original', or whatever you want (I'll use
'main').

2. Add the following function at the top of your m-file.

function varargout = myFunc(fid, varargin)
if ~exist('fid','var')
% add your default action for this m-file. Like...
help myFunc
disp('It needs a function name to call.');
return;
end
fh = str2func(fid);
[varargout{1:nargout}] = fh(varargin{:});

Note that the function name should match the m-file name, which is
'myFunc' in this case.

Caution: There is one problem to this approach. You have to update all
calls to the original myFunc like following.

From
[out1, out2, ...] = myFunc(param1, param2, ...)
To
[out1, out2, ...] = myFunc('main', param1, param2, ...)

Now you can call any of your other functions in this m-file by running

myFunc('mySub_A', a, b);
[e, f] = myFunc('mySub_B', c, d);

and so on. Inspect this skeleton file for more detail. (Read comments
carefully.

<< END >>

Cite As

Sung Soo Kim (2024). Tip: calling subfunctions from outside m-file (Final) (https://www.mathworks.com/matlabcentral/fileexchange/23124-tip-calling-subfunctions-from-outside-m-file-final), MATLAB Central File Exchange. Retrieved .

MATLAB Release Compatibility
Created with R14SP3
Compatible with any release
Platform Compatibility
Windows macOS Linux
Categories
Find more on Debugging and Analysis in Help Center and MATLAB Answers

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
Version Published Release Notes
1.6.0.0

codes were cleaned up. help was extensively updated.

1.5.0.0

copyright update

1.4.0.0

Final version. Just two lines of codes.

1.3.0.0

Hopefully final version. Very simple two line trick to access all subfunctions outside m-file.

1.2.0.0

Hopefully final version. Now it works for varargout as well.

1.1.0.0

No 'eval'. Super simple two line code snippet. Inspired by the comment of @us. Thanks to 'us'.

1.0.0.0