Brett's Pick this week is SetDefaultValue, by Richie Cotton.
Richie wrote in the File Exchange introduction to his SetDefaultValue submission that "it's so simple that I nearly didn't upload this, but it does make your functions cleaner." In fact, it is extremely simple, but it is also widely useful. Anyone who has ever written a program, function, or algorithm--in MATLAB or in any other language--has likely had to deal with variable initializations umpteen times. Many of us have come up with clever ways of simplifying the process or, as Richie might say, "prettifying" the code.
SetDefaultValue cleverly uses simple evalin and assignin calls to streamline and prettify the process.
For instance, to conditionally set x to 1 and y to 3 as defaults, one might write:
if nargin < 1 || isempty(x) x = 1; end if nargin < 2 || isempty(y) y = 3; end
Richie's submission introduction referred to Loren's blog about setting defaults. Loren described the use of a switch/case approach, switching based on the number of input arguments. That is a perfectly reasonable approach, and one that I've used many times.
My personal style usually has me writing something along these lines:
% FUNCTION SYNTAX: foo(reqdArg1,reqdArg2,varargin) % Defaults x = 1;y = 2; if nargin > 2, x = varargin{1};end if nargin > 3, y = varargin{2};end
With Richie's function, one could replace those lines with these:
SetDefaultValue(1, 'x', 1); SetDefaultValue(2, 'y', 3);
Sometimes, the simplest functions are the most useful ones!
Anyone else have any clever ways to share for dealing with default values? Share them, or your thoughts on the approaches mentioned here, using the comments box below.
Get
the MATLAB code
Published with MATLAB® 7.10


I recommend people look at the inputParser object (doc inputParser). This is very useful for writing functions with a mix of required inputs, optional inputs, and optional parameters.
In general I think it is not good practice to check for function arguments by checking nargin as shown in the article. This makes it impossible to skip a parameter but assigning a later one. E.g.
to find the maximum values in rows of a matrix.
Checks like the following are more robust:
function foo(bar1, bar2) if ~exist('bar1', 'var') || isempty(bar1); bar1=default1; end if ~exist('bar2', 'var') || isempty(bar2); bar2=default2; endThis also allows a call like
Andreas,
An empty input argument is not the same as a missing input argument.
function showNargin(varargin) fprintf('You passed in %d inputs.\n', nargin);Now call this function with the inputs you used in your MAX call:
It will display “You passed in 3 inputs.”
Steve,
i am aware that an empty variable is something different than one which has not been passed. Still, in my opinion a solution using exist is better than checking nargin.
E.g. the following code doesn’t require the user to pass the position of the argument to SetDefaultValue which makes it less fragile in case of function prototype changes.
function SetDefaultValue(argName, defaultValue) if ~evalin('caller', ['exist(''' argName ''', ''var'')']) || ... isempty(evalin('caller', argName)) assignin('caller', argName, defaultValue); end endI can’t test the code here so there might be some bugs included, but something like that should work fine. The only downside I see is that the additional function call will have a negative performance impact over the simple logic compare.
Just my 5c.
I second Eric. The addition of inputParser to the language took away all of these problems for me.
At work we have a standard function template which handles varargins and setting default values.
As in the example, set default values, then parse the inputs. We use a loop to parse the pairs of varargins ie
would call:
var1= 10; anothervar = 'a string' vaues = [1 2 3; 5 6 7] for 1=1:2:narargin eval([varargin{i},' = ',varargin{i+1}]); endalso, we have a function for checking that all values in a structure are set, and if not sets them to their default values,
defaults = {'foo', [1 2 3; 4 5 6], 8}; fields = {'string','matrix','value'} s = check_structure(s, defaults, fields)@Eric (and Richard): thanks for the mention of the inputParser. It does indeed obviate these shortcuts and workarounds that we’re discussing. For those interested, read this:
http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/bresuxt-11.html.
Note (Mike) that the inputParser also provides a way of managing Parameter-Value pairs quite nicely!
I recognize (as I would guess Richie does) that passing in an empty argument is not the same as passing no argument, so yes, one must be careful with NARGIN-type syntaxes. Still, I like Richie’s approach because, it solves the problem in a way that is comfortable to him and which meets his needs. (I’d guess that others might find the same to be true.) Also, I had hoped that this pick would spark an interesting and fruitful discussion…great comments!
Is there (easy) way to check which version a function/feature is introduced in?
Unfortunately, Wei, I don’t think there is an easy way. If you dig–search the doc, and search the Support Tab at MathWorks.com–you can often find a reference to the release notes for a function. For instance, for the INPUTPARSER, one might dig around and find this document:
http://www.mathworks.com/access/helpdesk/help/techdoc/rn/bq08o1n-1.html
It describes some of the new functionality made available with R2007a–including the functionality of the InputParser.
Regards,
Brett
@Brett, It’s just that it’s not easy. A search for inputParser turns out 7 pages and your link is on page 5.
TMW can help its users by improving web, and doc, search capability. For example a qualfied searched which leads to this release note would be very nice. A search can produce all new functions/feature since a given release and in a set of toolboxes etc.
Thank you,
@Wei…
I’ll share your comments with our doc writers, Wei. And I’d encourage you to at least skim through the release notes for any products you have licensed. That’s the best way to keep current.
@Wei…
Update: As promised, I shared your comments with our documentation team. I’ve been assured that your request has been heard (and heard before), and that they are working on a solution.
I prefer
, should be available via file exchange.