Why am I unable to run a subfunction from outside its main function or as a callback function?

8 views (last 30 days)
If I create a function file:
function y=myfun(x)
y=2*x;
function t=mysubfun(z)
t=3*z;
and try to call mysubfun in a callback for a uicontrol or from the MATLAB command prompt, I receive the following error message:\n
ERROR: mysubfun(3)
??? Undefined function or variable 'mysubfun'.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 5 Oct 2020
Edited: MathWorks Support Team on 6 Oct 2020
The reason MATLAB returns the "Undefined function or variable" error is that the subfunction is not in scope when you try to run it from the command line or as a callback.
If you are trying to create an object inside a function MATLAB file while defining that object's callback to be a subfunction within the MATLAB file, then the best way to do this would be to use a function handle. The function handle is a feature that is available as of MATLAB 6.0 (R12). Using a function handle will tell the callback to use the function that is in scope at the time of declaration of the function handle. In this case, the function in scope would be the subfunction. The following example function can be used as a guide:
function simplegui
% Main function to create a simple GUI
uicontrol('Style','PushButton','Units','Normalized','String','Push Me','Callback',@pbcallback);
function pbcallback(hobj,ed)
% Notice that the function handle callback requires at least 2 input arguments
% HOBJ - The handle to the callback object
% ED - The event data (not used)
pos = get(hobj,'Position');
pos(3:4) = rand(1,2).*(1-pos(3:4));
set(hobj,'Position',pos)
For more information on the input argument requirements for function handles, see the following online documentation:
Additionally, here are two ways you can call a subfunction from the command line indirectly. The first method works in MATLAB 6.0 (R12) and later versions of MATLAB, while the second works in MATLAB 5.3 (R11) and later.
For MATLAB 6.0 (R12) and later versions:
The first method to call a subfunction from outside a main function is to create a function handle to the subfunction inside the main function (where the subfunction is in scope) and return it as an extra output argument. You can then use FEVAL to evaluate the function handle, passing it any arguments the subfunction accepts. The reason this works is that a function handle records the scope of the function or subfunction in which it was created. A simple example of how to do this is:
function y=myfun(varargin)
if nargin==0 % There are no input arguments, I assume you are asking for the function handle
y=@mysubfun; % This only works in MATLAB 6.0 (R12) and above
else % There is an input argument, I assume you want to evaluate the main function
y=2*varargin{1};
end
function t=mysubfun(z)
t=3*z;
Now, if you type:
H=myfun;
y1=myfun(1);
y2=feval(H,1);
[y1 y2]
You receive the result:
ans =
2 3
NOTE: To do this you will need to call your main function at least once before calling the subfunction.
For MATLAB 5.3 (R11) and later versions:
The second way to call a subfunction from outside its main function is to create a FEVAL switchyard inside your main function. You can then call the subfunction by passing the name of the subfunction to your main function and using FEVAL to evaluate it inside the workspace of the main function. The subfunction will be in scope in that workspace. The code below is an example of how to use this technique:
function y=myfun(varargin)
x = 2;
if nargin>=2 % You passed the name of the subfunction and an input value for it
y=feval(varargin{1},varargin{2});
elseif nargin==1 & ischar(varargin{1}) % You passed the name of the subfunction, using the default value
y=feval(varargin{1},x);
elseif nargin==1 % You passed an input value to the main function
x=varargin{1};
y=2*x;
else
y=2*x; % You didn't pass anything, using the default value in the main function
end
function t=mysubfun(z)
t=3*z;
You can call this main function in one of four ways:
y1=myfun;
y2=myfun(1);
y3=myfun('mysubfun');
y4=myfun('mysubfun',1);
[y1 y2 y3 y4]
This code will return:
ans =
4 2 6 3
The first value is 2 times the default value of 2, the second is 2 times the input value of 1, the third is 3 times the default value of 2, and the fourth is 3 times the input value of 1.
Note the use of the VARARGIN and NARGIN functions in the code above. The VARARGIN function allows the main function to accept any number of input arguments to be stored in a cell array and parsed in the main function. The NARGIN function returns the number of input arguments passed to the function in which it appears.

More Answers (0)

Categories

Find more on Programming Utilities in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!