Parsing varargin for a function called with values only instead of name-value pairs

9 vues (au cours des 30 derniers jours)
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?

Réponse acceptée

Sean de Wolski
Sean de Wolski le 8 Oct 2018
Modifié(e) : Sean de Wolski le 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.

Plus de réponses (2)

Jeff Miller
Jeff Miller le 8 Oct 2018
With ExtractNameVal, you could include lines like the following in your function:
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
Adam le 10 Oct 2018
Modifié(e) : Adam le 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.

Catégories

En savoir plus sur Argument Definitions dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by