MATLAB: Is the parameter-value argument pair incorrectly interpreted as an optional argument by the function INPUTPARSER in MATLAB 7.8 (R2009a)

MATLAB

I have a function which should be callable in the following ways:
1. myFunction()
2. myFunction('myfilename')
3. myFunction('myfilename','param1','val1')
4. myFunction('param1','val1')
The function has an optional argument named "filename" and an optional parameter-value pair with parameter name "param1".
The following code uses the function INPUTPARSER for the above situation:
function myscript(varargin)
p = inputParser;
p.addOptional('filename',[],@ischar);
p.addParamValue('param1',[],@ischar);
p.parse(varargin{:});
p.Results
This works correctly for situations 1-3, but in situation 4 I receive an error:
>> myFunction('param1','myval1')
??? Error using ==> myFunction at 5
Parameter 'myval1' does not have a value.

Best Answer

The issue is that in the call
myFunction('param1','myval1')
the first argument 'param1' is interpreted as the "filename" argument. This is because the string 'param1' passes the validator for "filename" i.e.
ischar('param1') == 1.
To prevent the parameter-value pair from being interpreted as an optional argument, a stricter validator should be defined for the "filename" argument is possible e.g. a validator that checks whether the argument ischar AND NOT equal to the string 'param1':
p.addOptional('filename',[],@(x) ischar(x) & ~strcmp(x,'param1'));
If there are more parameter-value pairs a validator function can be written which checks that the filename argument does not match any of the other argument names. An example of such a function would be:
function myFunction2(varargin)
p = inputParser;
p.addOptional('filename',[],@(x) strictValidator(x,p));
p.addParamValue('param1',[],@ischar);
p.addParamValue('param2',[],@ischar);
p.parse(varargin{:});
p.Results
function y=strictValidator(x,p)
% Check whether the parameter ischar AND that it is NOT equal to the
% name of any of the other parameters
y = ischar(x) && ~any(strcmp(x,p.Parameters));
It should be noted that in the above example it is not possible to have "filename"='filename'. In other words the call
MyFunction2('filename')
will fail (because the string value 'filename' is also the name of an argument).