tags:

views:

115

answers:

4
+4  Q: 

nargin vs exist

Hi

Given a function like:

function foo(myParam)
if nargin<1
  myParam = 'default value';
end % if
end % function

I've seen people use something like the following in the place of the nargin version

if ~exist('myParam', 'var')
  myParam = 'default value';
end %if

I'm wondering if there is any preference either way?

The "~exist..." version to me has the advantage that if I change the order of my function parameters then it should still work. However my concern with this approach is that I might inadvertently pick up variables that are defined globally or in the scope of a surrounding function in the case of nested functions.

Any thoughts on the issue?

+5  A: 

I would go with nargin for two reasons:

  1. If you change the order of parameters to your function, fixing up the input checking code is going to be the least of your problems; you're going to have to go update all the call sites to your function as well.

  2. nargin is far cheaper. exist, even if scoped to just check for variables, has to scan the whole workspace doing a bunch of string comparisons along the way. the nargin method consists of just a scalar less than operation.

SCFrench
+6  A: 

Both should work. But...

Exist tends to be slow, since it must look through your workspace for the variable in question. When you write error checks like this, you don't want them to suck up CPU cycles. The test against nargin is a simple test against a single numeric value.

I'd also generally suggest a more extensive test. Something like

if (nargin<1) || isempty(myparam)

myparam = defaultvalue;

elseif

...

end

Inside the elseif branch, I'll put a set of additional tests to see if the parameter has the expected size, shape, class of variable, etc. If those tests fail, I'll return a friendly error message that explains what was wrong.

woodchips
+3  A: 

I always validate arguments using nargchk, and then go with the nargin tests as you had them. As others pointed out, they're cheaper, and I think clearer.

In functions that I expect to be re-used heavily, I always put lots of checks up front, and then structure the code to call the real implementation later.

I also tend to structure optional arguments (when not using varargin) like this:

function x = myfcn( arg1, opt_arg2 )
if nargin < 2
   arg2 = 'default';
else
   arg2 = opt_arg2;
end

as I think this makes it more obvious when editing the file which arguments are expected to be optional.

Edric
+2  A: 

I'd go with the NARGIN option, for the reasons listed by SCFrench. One additional benefit: I often find myself using it in conjunction with a SWITCH statement when I have more than 2 input arguments:

function outArgs = my_fcn(inArg1,inArg2,inArg3)
  switch nargin,
    case 0,  % No input case
      error('Not enough inputs!');
    case 1,  % Set last 2 inputs to default
      inArg2 = 'yes';
      inArg3 = 'on';
    case 2,  % Set last input to default
      inArg3 = 'on';
  end
  ...
  % Checking of variable types and values would go here! 
  ...
end
gnovice

related questions