Version of inputname to call outside of a function?
1 view (last 30 days)
Show older comments
Essentially, I'm looking for a way to get the names of inputs to a function. I know you can get the number with nargin...
I'm writing a testing framework, so i want to be able to provide the name of the function to the framework and have it prompt the user for test values.
3 Comments
Stephen23
on 6 Nov 2018
The names that are used for input/output arguments when a function is called are totally unrelated to the names that are used in the function's internal workspace, and it would be a pointlessly slow process to try and find them out. Such introspective programming is not efficient.
Answers (2)
TADA
on 5 Nov 2018
Edited: TADA
on 5 Nov 2018
If it's a function I don't think there's a builtin way to inspect it like that, however for anonymous functions you can parse the function using func2str and with .m files you can parse the file itself
function [args, status] = inspectArgs(foo)
% This function takes in a function handle and finds its decleration
% with .m file functions and scoped functions, the declaration is found
% within the .m file
% with anonymous functions, the decleration is found using func2str
status = 'ok';
% Get function content for anonymous functions and function name for
% .m file functions
fullFuncName = func2str(foo);
match = regexp(fullFuncName, '^@\((?<args>[^\)]*\).*', 'names');
if ~isempty(match)
% anonymous functions
args = regexp(match.args, '\s*,\s*', 'split');
return;
end
path = which(fullFuncName);
declerationPostfix = '';
if exist(fullFuncName, 'builtin')
% builtin functions
tok = regexp(path, '\((?<fname>.*)\)','names');
path = tok.fname;
if length(path) < 3 || ~endsWith(path, '.m', 'IgnoreCase', true)
path = [path '.m'];
end
% Builtin functions .m files may have a function declerations
% without the function keyword
declerationPostfix = '?';
elseif isempty(path)
% Scoped functions
info = functions(foo);
if ~isempty(info.file)
path = info.file;
else
status = 'file not found';
args = {};
return;
end
end
% truncate namespaces
dotIndex = find(fullFuncName == '.', 1, 'last');
if isempty(dotIndex)
funcName = fullFuncName;
else
funcName = fullFuncName(dotIndex+1:end);
end
% Read .m file
fid = fopen(path, 'r');
text = fread(fid, '*char')';
fclose(fid);
% find function decleration
match = regexpi(text, ['(function\s*(\[?[\w\,\s]*\]?\s*=)?\s*)' declerationPostfix funcName '\([^\)]*\)'], 'match', 'once');
if isempty(match)
args = {};
status = 'parse error';
else
% Find foo(args)
match2 = regexpi(match, [funcName '\([^\)]*\)'], 'match', 'once');
% crop only the args part
argString = strtrim(match2(length(funcName)+2:end-1));
if isempty(argString)
args = {};
else
args = regexp(argString, '\s*,\s*', 'split');
end
end
end
0 Comments
Walter Roberson
on 6 Nov 2018
Edited: Walter Roberson
on 6 Nov 2018
Take advantage of the function signatures that MATLAB itself uses.
0 Comments
See Also
Categories
Find more on Argument Definitions 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!