I wrote a test function, and ran into trouble with inputParser
function doit(varargin)
p = inputParser;
p.KeepUnmatched = 1;
% why does this bomb if I put in @ischar ?
p.addOptional('shape','forgot',@(x) true);
p.addParameter('color', 'k', @(x) true); % 'cause color could be char or triplet
p.parse(varargin{:});
% more code using the parsed inputs
end
If I run
doit('hello','color','g')
or
doit('color','g')
with the code as above, all works as expected. But if I change the input validation for the optional argument to
p.addOptional('shape', 'forgot',@(x) ischar) , I get an error at p.parse(varargin{:})
No value was given for 'g'. Name-value pair arguments require a name followed by a value.
It looks like I'm not understanding what the final argument, the anonymous function that's supposed to validate the input argument. What's the fix?
edit:
Matlab 2015a on Win7 .
edit 2: variational test cases
It appears that exactly what class each argument in varargin is affects the behavior.
function threeout = argthree( varargin)
p = inputParser;
p.KeepUnmatched = true;
%defshape = 'forgot';
defshape = 5;
addOptional(p,'shape',defshape,@isnumeric);
addParameter(p,'color', 'k',@ischar); %
parse(p, varargin{:});
threeout = p.Results;
end
There are at least two things that can cause parse() to fail. First: this :
>> argthree('nono','color','vu')
Error using argthree (line 10)
No value was given for 'vu'. Name-value pair arguments require a name followed by a value.
Notice that even though the Optional "shape" is supposed to be tested for numeric, the parser appears to think "nono" is the start of a name-value pair.
Entering either a numer or nothng works:
>> argthree('color','vu')
ans =
color: 'vu'
shape: 5
>> argthree(7,'color','vu')
ans =
color: 'vu'
shape: 7
Now replace the addOptional line with no validation:
addOptional(p,'shape',defshape );
Get the same results as above for all three calls.
Now change the default to
defshape = 'forgot' % a charstring
>> argthree('nono','color','vu')
Error using argthree (line 10)
No value was given for 'vu'. Name-value pair arguments require a name followed by a value.
>> argthree('color','vu')
ans =
color: 'vu'
shape: 'forgot'
>> argthree(7,'color','vu')
ans =
color: 'vu'
shape: 7
Now try validating the string input: replace the addOptional line again-
addOptional(p,'shape',defshape,@ischar );
>> argthree('nono','color','vu')
ans =
color: 'vu'
shape: 'nono'
>> argthree('color','vu')
Error using argthree (line 10)
No value was given for 'vu'. Name-value pair arguments require a name followed by a value.
>> argthree(7,'color','vu')
Error using argthree (line 10)
The value of 'shape' is invalid. It must satisfy the function: ischar.
There's something very inconsistent here with how parse() tries to match varargin{:} to the parameter list (optional or name-value pair). Due to the inconsistent failures happening, I can't set up a situation with an Optional char argument followed by a name-value pair, so far as I can see.
update
I've filed a bug report at MathWorks, "Technical Support Case #02121531" and they were able to reproduce the problem .
p.addOptional('shape', 'forgot', @(x) ischar(x) )- Trogdor