Parsing varargin for a function called with values only instead of name-value pairs
18 views (last 30 days)
Show older comments
Suppose I am writing code to maintain a bird-watching database. Each optional input to this function has a rather short list of possible options:
'bird' : 'robin', 'cardinal', 'bluejay'
'where' : 'Mendon Pond', 'Grand Canyon', 'Seattle'
'when' : 'morning', 'afternoon', 'dusk', 'evening'
Because there are only a few options for the values for each name in the varargin, it seems to me that a function call like:
add_to_database(db, 'robin', 'Grand Canyon', 'dusk');
is as clear and easy to parse as
add_to_database(db, 'bird', 'robin', 'where', 'Grand Canyon', 'when', 'dusk');
That is, when an input parser sees 'robin', it knows that it is a value for the name 'bird,' and so there is no point in passing the 'bird' name first.
1) inputParser and the contributed packages on the MATLAB Central File Exchange don't seem to be designed for this sort of input parsing... is that a correct assessment?
2) Is there a reason why contemplating parsing varargin in this way is a bad / un-MATLAB-y idea? If the dictionary of options grows over time and then the same value could be used for more than one name, then obviously the jig is up... but barring that, is there a reason that an input parser for something like this doesn't exist?
0 Comments
Accepted Answer
Sean de Wolski
on 8 Oct 2018
Edited: Sean de Wolski
on 8 Oct 2018
I like name-value pairs because it makes it easier to extend in the future if you need a new option. With the ability to have auto suggestions added in 18a, it makes it easier to quickly tab through them as well. So even if there's more typing, the command is clearer and order doesn't matter if you forget it; e.g:
addBird('robin', 'when', 'dusk','where','feeder')
addBird('eagle', 'where', 'squirrel nest', 'when', 'evening')
For the above the inputParser would have addRequired for bird, and addParameter for when, where. Note, I'm running this in 18b where double quote "strings" are supported everywhere. Earlier releases you may need to use cellstr/char arrays.
p = inputParser;
p.FunctionName = 'addBird';
p.addRequired('Bird',@(x)validateattributes(x, {'string'}, {'scalar'}));
p.addParameter('When',"morning",@(x)validateattributes(x, {'string'}, {'scalar'}));
p.addParameter('Where',"seattle",@(x)validateattributes(x, {'string'}, {'scalar'}));
parse(p,"eagle");
bird = validatestring(p.Results.Bird, ["robin","eagle","sparrow"])
when = validatestring(p.Results.When, ["morning","dusk","evening"])
where = validatestring(p.Results.Where, ["seattle", "feeder"])
You can use the addOptional or addRequired options with inputParser to get the behavior you described in your post.
Also look at validatestring() as the validator.
0 Comments
More Answers (2)
Jeff Miller
on 8 Oct 2018
if ExtractNamei('robin',varargin) % 'i' indicates case-insensitive version
% do something
elseif ExtractNamei('cardinal',varargin)
% do something
elseif ExtractNamei({'bluejay','blue-jay','blue jay'},varargin) % allow alternative spellings
% do something
else
% do something
end
Adam
on 10 Oct 2018
Edited: Adam
on 10 Oct 2018
function add_to_database(db, bird, where, when)
if ~isempty( bird )
bird = validatestring( bird, { 'robin', 'cardinal', 'bluejay' } );
end
if ~isempty( where )
where = validatestring( where, { 'Mendon Pond', 'Grand Canyon', 'Seattle' } );
end
if ~isempty( when )
when = validatestring( when, { 'morning', 'afternoon', 'dusk', 'evening' } );
end
...
is probably what I would do if I were using this as a setup. I would likely define those cell arrays of valid strings elsewhere, but that is just semantics, e.g. I use classes mostly so I would define them as Constant properties at the top of the class and extend them as needed. Then the same set of valid names can be used in multiple places too.
This doesn't use varargin, but then given the strictness of your constraints on the inputs I don't see why varargin would be required rather than named inputs.
0 Comments
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!