How to show the inputs to a function from within?

18 views (last 30 days)
I'm trying to show (for debugging purposes) the input values to a function from within that function. If the inputs are provided through varargin, then a simple loop will do it:
output = myfun(varargin)
fprintf('\n%s was called with the following inputs:',mfilename)
for i = 1 : nargin
fprintf('\n\t%s',varargin{i})
end
But if the function takes required inputs, then I cannot use the loop above but have to actually name all the inputs directly:
output = myfun(x,y,z)
fprintf('\n%s was called with the following inputs:',mfilename)
fprintf('\n\t%s',x)
fprintf('\n\t%s',y)
fprintf('\n\t%s',z)
This is cumbersome if there are many inputs. Also, it doesn't allow to copy-paste the nice loop to any function I want - I have to edit it for each function depending on the number and names of the inputs.
So the question is: Is there a way to do this with a loop? Essentially I would have to collect the input-names in a cell (like varargin) and then loop over that cell. But how to do this???
Note that the function inputname() doesn't solve this - it gives the name of the workspace variable, but I don't want the variable name, I want the value.
Thanks to everyone!

Accepted Answer

Guillaume
Guillaume on 13 May 2015
Edited: Guillaume on 13 May 2015
Matlab does not offer this kind of inspection functionality. The only way I could think of getting this would be to write your own function that would parse the m code of the function and use evalin to grab the values of all the inputs of the function. Something like:
%the function for which you want to see the inputs:
function output = myfun(x, y, z, varargin)
displayinputs(mfilename('fullpath'));
%rest of function ...
end
%function that parse and display inputs of another function:
function displayinputs(functionpath)
%functionpath: the full path of the function m file.
%Obviously does not work for local subfunctions, nested functions, or class methods
code = fileread([functionpath '.m']);
[~, fname] = fileparts(functionpath);
argsegment = regexp(code, sprintf('(?<=function.*?%s\\s*\\(\\s*)[a-zA-Z0-9_]+(?:\\s*,\\s*[a-zA-Z0-9_]+)*(?=\\s*\\))', fname), 'match', 'once');
args = strsplit(argsegment, ',');
fprintf('\n%s was called with the following inputs:\n', fname);
for arg = args
arg = strtrim(arg{1}); %#ok<FXSET>
if strcmp(arg, 'varargin')
vin = evalin('caller', 'varargin');
for nin = 1:numel(vin)
disp(vin{nin});
end
else
varg = evalin('caller', arg);
disp(varg);
end
end
end
The above is totally untested and probably full of bugs. Note that the regular expression looking for the function declaration in the m file can easily be defeated by comments.
Also note, that the fprintf in your examples only work when the variables contain string.
edit: actually tested the function and fixed some bugs. It seems to work

More Answers (1)

Yoel Lax
Yoel Lax on 13 May 2015
Cumbersome, but nice! Thank you very much!!

Categories

Find more on Argument Definitions in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!