Error when using validatestring in inputParser addOptional
10 views (last 30 days)
Show older comments
I'm getting the following error when running isenExpan('a','m',2,1.4,'sub') with the code below:
??? Error using ==> isenExpan
Argument 'sonic' failed validation
@(x)validatestring(x,validSonic).
code:
function out = isenExpan(from,to,val,gam,varargin)
%%error checking
validTypes = {'m', 'a', 'p', 't', 'd'};
validSonic = {'super', 'sub'};
p = inputParser;
p.FunctionName = 'isenExpan';
p.addRequired('from', @(x)validatestring(x,validTypes));
p.addRequired('to', @(x)validatestring(x,validTypes));
p.addRequired('val', @isnumeric);
p.addRequired('gam', @(x)validateattributes(x,{'numeric'},{'>',1,'<',1.5}));
p.addOptional('sonic', 'super', @(x)validatestring(x,validSonic));
p.parse(from,to,val,gam,varargin{:});
I'm giving sonic a valid input, and when I step through itin debug mode, validatestring returns 'sub' and not false.
Has anyone else seen or heard of this problem?
1 Comment
David Ternet
on 12 Aug 2013
Another question related to this. Is anyone else frustrated by the way many of these APIs rely on exceptions or text display results? For example, why couldn't validatestring (or inputparser.parse) return a simple true/false instead of using an exception to indicate failure? It seems a bit costly to add try/catch blocks around many of these API calls just to find out if something was successful or not.
Accepted Answer
Sven
on 3 Feb 2012
Hi Kevin,
The problem lies in validatestring... from the docs: "the validatestring function returns the matching string in validstr". So it returns the matching string, rather than TRUE, FALSE, or nothing (as required by inputParser).
Try changing that line to:
p.addOptional('sonic', 'super', @(x)any(strcmp(x,validSonic)));
EDIT:
Actually, I can see why we would expect it to work... it seems that inputParser.parse has no trouble when validatestring returns the string (rather than an error) to a required argument, but it seems not to like the same validation of an optional argument... weird...
The proposed solution still works just as well, but I'm a little perplexed about why the problem occurred in the first place. Unfortunately inputParser.parse() is an internal MATLAB function, so there's no chance to follow the code inside and see why it goes wrong.
3 Comments
Adam Danz
on 2 Jan 2020
Edited: Adam Danz
on 3 Feb 2020
validatestring() returns a string scalar if validStrings is a string array or it returns a character vector if validStrings is a cell array of character vectors. Therefore, depending on which type of data you're using (string array or cell array of characters),
@(x)ischar(validatestring(x,validStrings))
@(x)isstring(validatestring(x,validStrings))
Note that in either case, 'x' can be a cell array or a string but the output will always match the class of validStrings (tested in r2019b).
An alternative validation would be
@(x)assert(ismember(x,validStrings),'Accepted inputs are\n%s',validStrings))
or for case insensitivity
@(x)assert(ismember(lower(x),lower(validStrings),'Accepted inputs are\n%s',validStrings))
or use any(strcmpi(x, validStrings))
More Answers (0)
See Also
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!