Understanding nargout(@plot) and detecting "varargout-only" functions

6 visualizaciones (últimos 30 días)
Matt J
Matt J el 23 de Jul. de 2018
Comentada: Jan el 23 de Jul. de 2018
I am trying to understand why nargout(@plot) returns 1.
>> nargout(@plot)
ans =
1
My ulterior motive is to be able to detect whether a function has varargout as its only only output argument in its function signature (and whatever the equivalent is for built-in functions).
According to the nargout documentation, a function handle to a function with only a variable number of output arguments,
function varargout=test(varargin)
will produce an nargout result of -1. This is corroborated by the following test and so seems like a good way to achieve what I am after.
>> nargout(@test)
ans =
-1
But surely plot() is in the same category. The 'ans' variable is unaffected when plot() is called with no output arguments.
>> ans=pi
ans =
3.1416
>> plot(1:5); ans
ans =
3.1416
Can anyone make sense of this behavior? If this is intended, then how can one auto-detect whether a function has a variable number of output arguments?

Respuestas (2)

Jan
Jan el 23 de Jul. de 2018
Editada: Jan el 23 de Jul. de 2018
plot is a built-in command. It can have 1 output argument, such that nargout(@plot) is expected to reply 1.
But surely plot() is in the same category
Why are you sure? A built-in or Mex function is allowed to reply one output, but can leave the output undefined also. Then ans is not created or overwritten.
// file: myAnsTest
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
if (mxGetScalar(prhs[0]) == 1.0) {
plhs[0] = mxCreateDoubleScalar(3.14);
}
}
Now compile and call it:
ans = -1
myAnsTest(0)
ans
myAnsTest(1)
ans
I assume, that an auto-detection of the number of outputs is meta-programming. Are you really sure that this is useful for your work?
  6 comentarios
Adam
Adam el 23 de Jul. de 2018
I tend to use narginchk quite often and nargin on a function handle that I am passing in to use as a callback and I am going to be passing the arguments to it so I like to assert on nargin just for extra security, though I tend to only do this for functions that should have fixed input arguments rather than varargin. I'm not sure I've ever found much use for checking nargout, although I suppose the same reasons as checking nargin maybe hold.
Jan
Jan el 23 de Jul. de 2018
@Matt J: There are 2 cases:
  1. Using nargin and nargout inside a function: Here the function examines how it was called and the results concern the current state of Matlab. This is not an analysis of code. Not "meta".
  2. nargout(@fun) checks the properties of other functions. The source code it examined to do this: "meta".
I never use the 2nd method. Most of all not in productive code. Yes, I admit, I've written some unproductive code also: E.g. a tool which checks offline if all M files with constructs like:
try
catch ME
disp(ME.message)
end
use a correctly spelled "message" and not "meesage". This typo can be found by exhaustive checks of all exceptions in the unit-tests, but it is not trivial to prove, that the tests are exhaustive. Therefore I use a tool to check these symbols automatically. But as said, this does not run during the productive work, but offline during the unit-testing.

Iniciar sesión para comentar.


Steven Lord
Steven Lord el 23 de Jul. de 2018
My ulterior motive is to be able to detect whether a function has varargout as its only only output argument in its function signature (and whatever the equivalent is for built-in functions).
Why? How are you planning to use this information?
Re: @plot.
Yes, plot does not assign a value to ans when it is called with 0 input arguments. I'm not certain exactly why that decision was made (it was made a Long Time ago, before I joined MathWorks) but I suspect it was to avoid confusion. If it did assign to ans when called with 0 inputs, it would have been (relatively) common to see something like "ans = 123.456789" (a Handle Graphics handle under the original Handle Graphics system) displayed when you ran your code. I think the assumption was that if you called plot with an output you cared about manipulating the graphics object after creation, but if you didn't you didn't care about the handle at all so why show it (and if you later on did decide you needed the handle, findobj exists.)
That does not mean it uses varargout or the equivalent for built-in functions.
  1 comentario
Matt J
Matt J el 23 de Jul. de 2018
Editada: Matt J el 23 de Jul. de 2018
That does not mean it uses varargout or the equivalent for built-in functions.
But then what does it mean? And how is nargout(fun) to be interpreted for built-in functions?
Why? How are you planning to use this information?
The motivation is a bit moot right now. In earlier versions of MATLAB, I was seeing problems with wrapper constructs like the following,
function varargout=wrapper(funchandle, varargin)
%Some code
[varargout{1:nargout}]=funchandle(varargin{:});
%More code
end
The problem was that, when nargout=0, a wrapper like the above would always return zero output arguments, which makes a lot of sense. But sometimes (depending on funchandle) you do want to return an output even when one is not requested. In fact, most stock Matlab functions behave this way, e.g.,
>> sind(90) %no outputs requested
ans =
1
I've only now noticed that this is no longer a problem in recent MATLAB, but in the days when it was, a check like what I've been asking about would have been the solution.

Iniciar sesión para comentar.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by