No BSD License  

Highlights from
loadOptions

from loadOptions by Nathaniel Brahms
Tool for implementing option name/value pairs in function arguments

loadOptions(defaults,args)
function options = loadOptions(defaults,args)

%LOADOPTIONS Loads option-value pairs into an options struct
%
%loadOptions can be used to create an option-value pair struct for
%functions, from function arguments.  This function allows for the user to
%choose default values for unspecified options, and specify types (i.e. a
%MATLAB class) for the option values.
%
%This is useful for functions that will typically be called with only a few
%options set from a large set of possible options.
%
%This function provides for typing of the option values.  If a class is
%specified for an option, values must be of that class or a subclass of
%that class, or an error results.
%
%Usage:
%
%   A function should be written as follows:
%       function <r> = userFunction(<arg1>,<arg2>,...,<argN>,varargin)
%   {arg1,...} are all the arguments to the user function that are not
%   options.  Option-value pairs will be loaded into varargin. The usage
%   of the user function will be as follows:
%       r = userFunction(arg1,arg2,...,argN,'Option1',value1,...)
%
%   Create a default options struct array, where each element has
%   the following fields:
%
%       defaults(i).name = <option name>
%           <option name> should follow the rules for naming variables:
%               - No special characters or spaces
%               - The first character must be alphabetic
%       defaults(i).value = <default option value>
%       defaults(i).class = [] | <MATLAB class name>
%           If defaults(i).class is empty, the option is untyped.  Note
%           that subclasses of defaults(i).class will be considered valid
%           options.
%
%   Now this struct should be passed along with varargin to loadOptions, as
%   follows:
%       options = loadOptions(defaults,varargin);
%
%   The fields of the options struct will be the option names, and the values
%   will be either the default values for those options not specified, or the
%   given values for those options specified in the function arguments.
%
%Example:
%
%   We wish to write a shift function for a bit register.  The options will be:
%       'RegisterSize' - Has a default of 8, must be a uint16
%       'SignBit' - Must be a boolean, default false
%       'Display' - Something to display at the end of the function, may be
%                   unsigned, default ''
%
%   Our function will be written:
%
%       function vOut = shift(v,delta,varargin)
%
%       defaults = struct('name',{'RegisterSize','SignBit','Display'},...
%                   'value',{8,false,''},'class',{'uint16','boolean',''});
%       options  = loadOptions(defaults,varargin);
%
%       if options.SignBit, start=2; else start=1; end
%
%       for i=start:options.RegisterSize
%           if i<delta+1, vOut(i) = 0;
%           else vOut(i) = v(i-delta); end
%       end
%
%       if ~isempty(options.Display), disp(options.Display); end
%
%   Now consider various user inputs:
%
%       >> shift(ones(1,8),2)
%       ans =
%           0   0   1   1   1   1   1   1
%
%       >> shift(ones(1,4),2,'RegisterSize',4)
%       ??? Error using ==> loadOptions at ---
%       'RegisterSize' must be of type 'uint16'
%
%       >> shift(ones(1,4),2,'RegisterSize',uint16(4))
%       ans = 
%           0	0	1	1
%
%       >> shift(ones(1,4),2,'RegisterSize',uint16(4),'Display','foo!')
%       foo!
%       ans = 
%           0	0	1	1
%
%       >> shift(ones(1,4),2,'RegisterSize',uint16(4),'Display',.01)
%           0.0100
%       ans = 
%           0	0	1	1
%
%       >> shift(ones(1,4),2,'RegisterSize')
%       ??? Error using ==> loadOptions at ---
%       Options must be name-value pairs
%
%       >> shift(ones(1,4),2,4,4)
%       ??? Error using ==> loadOptions at ---
%       Option names must be strings
%
%       >> shift(ones(1,4),2,'xyzzy',4)
%       ??? Error using ==> loadOptions at ---
%       'xyzzy' is not a valid option
%
% (c) 2007 Nathaniel Brahms and the Massachusetts Institute of Technology
%

% Author: N. Brahms
% Email: Contact via the Mathworks website
% Date: 11/18/2007
% Version: 1.0
% History:
%   Date        Version         Notes
%   --------------------------------------------------------------------
%   11/18/2007  1.0             First version


% args length must be even
if mod(numel(args),2)~=0
    error('Options must be name-value pairs');
end

names = cell(size(defaults));

% Loop over options
for i=1:length(defaults)
    names{i} = defaults(i).name;
    options.(names{i}) = defaults(i).value;
end

% Loop over option pairs
for iPair=1:length(args)/2
    
    if ~ischar(args{2*iPair-1})
        error('Option names must be strings');
    end

    % Finds the index in defaults corresponding to this option
    iOption = find(strcmp(names,args{2*iPair-1}),1);
    
    % The option was not found
    if isempty(iOption)
        error('''%s'' is not a valid option',args{2*iPair-1});
    end
    
    % If the option was found, extract the value and test its class if 
    % defaults(iOption).class is not empty
    test = args{2*iPair};
    if ~isempty(defaults(iOption).class) && ~isa(test,defaults(iOption).class)
        error('''%s'' must be of type ''%s''',defaults(iOption).name,...
            defaults(iOption).class);
    end
    
    % Output the option value
    options.(defaults(iOption).name) = test;
    
end % for iPair

Contact us at files@mathworks.com