Parsing varargin for a function called with values only instead of name-value pairs
17 ビュー (過去 30 日間)
古いコメントを表示
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 件のコメント
採用された回答
Sean de Wolski
2018 年 10 月 8 日
編集済み: Sean de Wolski
2018 年 10 月 8 日
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 件のコメント
その他の回答 (2 件)
Jeff Miller
2018 年 10 月 8 日
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
2018 年 10 月 10 日
編集済み: Adam
2018 年 10 月 10 日
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 件のコメント
参考
カテゴリ
Help Center および File Exchange で Argument Definitions についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!