Get names of input variables - problem with inputname()

23 views (last 30 days)
I would like to use the variables passed to a function with the variable names that were used during the function call (with a variable number of possible input arguments). I realize that there exists the function inputname() to help me realize this:
c = myFun(varargin)
for i = 1:nargin
strVarName = inputname(i);
switch strVarName
case 'a'
a = varargin{i};
case 'b'
b = varargin{i};
otherwise
error(['Unknown input parameter: ' strVarName])
end
c = a + b;
end
This works fine for me, but the code looks a bit ugly, so I wanted to move the loop to a script that was be called at the beginning of the function. Initially this worked fine, but suddenly I kept getting the error 'Unknown input parameter: ' – without having made any changes to the code! If I check it in debug mode, I either get an empty string for for inputname for all inputs, or the entire Matlab application crashes upon the function call inputname() – and sometimes, it also works perfectly fine. I moved the code back from the script to the original function, it seems to work more stable now, but I wonder whether there is any specific reason for this strange behaviour?
I am aware that there exist other solutions to get the input variables with their original names. But I do not want to use a struct or a cell array in this particular function (and even with parseInput I only get a struct), so the only other solution that I found was to use parameter/value pairs, i.e. a function call of the form:
myFun(‘a’,a,’b’,b)
But I would prefer the original function call for usability, unless there are some fundamental issues with the inputname() function – so my question is: is the inputname() function so fundamentally unstable that it would be wiser to sacrifice some usability and use a less user-friendly solution like parameter/value-pairs?
And do you have any better solution for achieving the desired functionality? Given that the function is called very often throughout my program, any suggestion for optimizing execution time would be very welcome.
Thanks!
PS: I am aware that inputname() returns an empty string when the variable passed is an expression, but this should not be the problem here (especially considering that the same code also works sometimes).

Answers (2)

Jan
Jan on 6 Mar 2013
This is a really bad programming method. You store essential information in the name of a variable. But the name should only be a name and kept separate from the contained data. Imagine you want to rename one of the variables in a function, but this has severe side-effects in the subfunction using your method. And this is something programmers want to avoid under all circumstances, because it let the effeort needed for debugging grow exponentially with the number of variables, code lines and subfunction.
So my advice is clear: Do not do this. You cen get better troubles for less money.
Anyhow, Matlab should not crash. You have obviously found a severe bug, which has not been revealed by others, because they avoid the evil inputname consequently. When you are able to reproduce it, please send a description to the technical support.

Christoph
Christoph on 6 Mar 2013
Edited: Christoph on 6 Mar 2013
I realize that this may look like bad practice, but the way my program works it seems like the most workable solution: I only have 4-5 variables in the entire program, which are nested structures with names like Config, Data, DataRaw,… and which contain all the actual variables. The specific function I was mentioning is a function called Overrides, which is intended to give the user control to edit any variable at (almost) any point during execution – which is why the function is called so often (with strings passed to identify at which point it is called). Now I want to be able to reference all variables with their usual path (like Data.TimeSeries.FX.vecEURUSD) in Overrides, and I cannot just make a fixed number of inputs to that function because not all variables exist all the time (DataRaw is not kept,…). Also, I want to have all the Overrides in a single file and I cannot make all the changes at the start because some adaptions require that a value has already been computed.
--> I figured that using the names of the input variables was the best solution to this problem, but if you have any better ideas I’d be very thankful!
Edit: I think I can reprocue the crashing problem, I will send a description.
  2 Comments
Jan
Jan on 6 Mar 2013
Please post comments as comments, because they are not answers.
Equivalent to Matlab's Handle Graphics system, you can add a field called "Type" to the structs:
% In the caller
Config.Type = 'Config';
Data.Type = 'Data';
% Inside the called function:
function c = myFun(varargin)
for k = 1:nargin
Arg = varargin{k};
switch Arg.Type
case 'Config'
Config = Arg;
case 'Data'
Data = Arg;
otherwise
error('Unknown input parameter: %s', Arg.Type);
end
You can move this to an extra function, which controls the modifications also:
function [Config, Data] = myParser(varargin)
Config = ... any defaults
Data = ... other defaults
% Now the code to identify the structs
...
% Finally the temporary changes:
...
You are very near to an object oriented approach then.
Go one step further: Why not storing all data in one struct? Then the fieldnames have the role of the former names of the variables, but in a direct and much saver and clearer way.
Christoph
Christoph on 6 Mar 2013
That's a great idea! The parser might be tricky, because it would need varargout, and then I'd be stuck with a similar problem in the Override function - but using a script instead should be fine.
Moving everything into one struct sounds neat, but I'll have to think trough it what it will mean in the entire program (in the display functions I load the Data struct from the disk and plan to combine the structs from various runs of the program).
Thanks for the help!

Sign in to comment.

Categories

Find more on Desktop in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!