Error when using validatestring in inputParser addOptional

10 views (last 30 days)
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
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.

Sign in to comment.

Accepted Answer

Sven
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
Kevin Holst
Kevin Holst on 3 Feb 2012
I've dug a little deeper and found that the reason it works on the required argument rather than the optional one is because the required one is a single character. If I make the optional argument a single character, it works fine. Weird.
Adam Danz
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))

Sign in to comment.

More Answers (0)

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!