How can I capture an unknown number of output arguments in a cell array in MATLAB 7.5 (R2007b)?

35 views (last 30 days)
I have a function 'foo' and I do not know how many arguments it takes. I want to capture all output arguments of 'foo' in a cell array. I would like to know how to do that without having to guess the number of output arguments.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 20 Jul 2009
To determine the number of output arguments for a given function FOO use the NARGOUT function:
nargout('foo')
If the function has a variable number of input arguments, NARGOUT returns a negative value. You can call NARGOUT with the name of a function, or the name of Function Handles that map to specific functions.
For example, for the following function definition:
function [a b c d] = foo()
a = 'albert';
b = 'barry';
c = 'charlie';
d = 'david';
The following command:
nargout('foo')
returns 4.
If a function handle is defined as:
myhandle=@foo
The following command will also return 4:
nargout(myhandle)
For more information about NARGOUT execute the following in the MATLAB command prompt:
doc nargout
Once the number of output arguments is known, you can write the arguments into a cell array as follows:
% allocate a cell array
mycell=cell(1,nargout('foo'));
% the first part of the string inside the square brackets:
str='mycell{1}';
% on each i-th step in the loop add another mycell{i} to the string 'str'
for i=2:nargout('foo')
s=[' mycell{' int2str(i) '}'];
str=strcat(str,s);
end
% add the square brackets
str=['[' str ']'];
% use EVALC function to evaluate the complete expression:
T=evalc([str '=foo()']);
T = evalc(S) is the same as eval(S) except that anything that would normally be written to the command window, except for error messages, is captured and returned in the character array T (lines in T are separated by \n characters).
For more information on the EVAL function, execute the following in the MATLAB command prompt:
doc eval
  2 Comments
Guillaume
Guillaume on 11 Sep 2017
That statement:
"If the function has a variable number of input arguments, NARGOUT returns a negative value."
is in direct contradiction of the doc. It would not make sense that the sign of nargout depends on the inputs.
nargout returns a negative if the function includes varargout.
Cris Luengo
Cris Luengo on 7 Jan 2020
Edited: Cris Luengo on 7 Jan 2020
`evalc` is a very ugly solution to this problem. It is not at all necessary here, as shown by Walter below.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 7 Apr 2016
mycell = cell(1,nargout('foo'));
[mycell{:}] = foo();
  4 Comments
Bill Greene
Bill Greene on 8 Jan 2019
When foo is an anonymous function handle this solution doesn't work because nargout(foo) returns -1. Is there a way to generalize this solution to handle this case also? My test code is:
function varargTest
foo= @() myFunc;
nout=nargout(foo)
mycell = cell(1,nout);
[mycell{:}] = foo()
end
function [a,b,c]=myFunc
a=2;
b=5;
c=8;
end
Walter Roberson
Walter Roberson on 7 Jan 2020
I do not think there is a way to generalize to this case. The anonymous function does not have a fixed number of outputs: the number of outputs depends upon the function(s) called inside the anonymous function.
You could use func2str() on the anonymous function, chop out the @() part, and then analyze the rest.
If it does not consist of a single call then nargout is 1 (or 0). In particular if it is an expression such as MyFunc(83)+cos(pi/11) then the '+' is an implicit function call and it happens that none of the operators ~ ^ .^ & && + - == {} [] \ | || : < > / ./ can return more than one output.
If it consists of something that looks like NAME(arguments) then you need probe whether NAME is a function or variable. If it is a function then you can nargout() it. If it is a variable then nargout is 1. But remember that you need to look inside the closure of the anonymous function because the NAME might have been captured.
If it consists of something that looks like NAME(arguments){expression} then that is invalid syntax.
If it consists of something that looks like NAME{expression} then you would need to probe whether NAME is a function or variable. If it is a function then that is invalid syntax. If it is a variable then you would need to execute to figure out how many returns there are.
If it consists if something that looks like NAME(arguments).NAME2 then you need to know which MATLAB release you are using. If NAME is a function then until around R2019a that was illegal syntax, but in a quite recent MATLAB release then it became valid to have a function return a struct or object and to dot reference it . But you would need to execute the function in order to determine whether the return was an object or a struct, because if it is a non-scalar object then dot referencing might be invalid. If the function executes to a non-scalar struct then nargout depends upon the size of the object returned...
There are more cases than these, but this should be enough to show you that there is no way to generalize the situation, that sometimes you cannot tell the number of outputs without executing the function or evaluating the indices.

Sign in to comment.

Categories

Find more on Argument Definitions in Help Center and File Exchange

Products


Release

R2007b

Community Treasure Hunt

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

Start Hunting!