How to show the inputs to a function from within?

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

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)

Cumbersome, but nice! Thank you very much!!

Categories

Asked:

on 13 May 2015

Answered:

on 13 May 2015

Community Treasure Hunt

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

Start Hunting!