Reputation: 5789
I create a function
function y = getValue(modelName, param, option)
open_system(modelName);
runModel(option);
y = getActiveFun(param);
end
I would like when calling this function to have the choice to pass or not argument option
from some other files I call the function with all arguments and sometimes I would like to call it without passing option
argument ?
I would like to call : getValue(modelName, param)
from other files
How could I do that ?
Upvotes: 5
Views: 4587
Reputation: 4787
While solutions with nargin
are already given and more or less a standard usage within most MATLAB codebases, I think there is a nicer alternative that is more readable.
With nargin
in big functions, you have to remember what argument 3 was exactly. Especially if you have more optional arguments, it becomes cumbersome to keep track or to allow that some optional arguments are passed, while others are not.
The first and easier solution is my personal alternative to nargin
, and that is using the exist
function:
function [output] = getValue(modelName,param,option, otherOption)
if ~exist('option', 'var') || isempty(option)
option = 'defaultValueForOption';
end
if ~exist('otherOption', 'var') || isempty(otherOption)
otherOption = 'defaultValueForOption';
end
% perform other actions
The advantage is that now all input-related code is at the beginning and it is more verbose as to what should be happening. You won't clutter your other code with that logic. And you can also supplement those if
statements with validation of the input and fall back onto the default when an invalid option is given.
The other possibility is standard in later versions of MATLAB: the inputParser
class. With this class, you can define even more complicated scenarios of optional parameters and even key-value pairs.
Below is a self-descriptive example I have kept to avoid needing the documentation every time.
%% Usage Example input Parser
%
function output = FuncName(rParam1, rParam2, oParam1, oParam2, varargin)
p = inputParser();
defaultValue = 0;
validatorFunc = @(x)(true); % validator function should return true when x is valid
%% Input Format definition
p.addRequired('rParam1', validatorFunc);
p.addRequired('rParam2', validatorFunc);
p.addOptional('oParam1', defaultValue, validatorFunc);
p.addOptional('oParam2', defaultValue, validatorFunc);
p.addParamValue('kvParam1', defaultValue, validatorFunc);
p.addParamValue('kvParam2', defaultValue, validatorFunc);
p.addParamValue('kvParam3', defaultValue, validatorFunc);
p.addParamValue('kvParam4', defaultValue, validatorFunc)
%% Optional Settings
% expand supplied struct to ParamValue pairs (or other arguments)
p.StructExpand = true; % default: false
%% Parse
p.parse(rParam1, rParam2, oParam1, oParam2, varargin{:})
%% Retrieve results
values = p.Results(); % structure with all values
defaultedArgs = p.UsingDefaults; % cell array of all parameter names using defaults
end
This approach is even more verbose and personally, I don't quite like the fact that one has to redefine for every input whether it is required or optional and that it requires quite a lot of boilerplate code. But at least, it is a solution that is a standard solution and without a doubt to be preferred for larger functions.
Both approaches do suffer from a drawback compared to the nargin
way of checking: they are both slower. So if you use these in functions that get called a lot (or only perform a very quick calculaion), it might be more worthwhile to use nargin
instead.
Upvotes: 2
Reputation: 121
For completeness, lets see the basics (see documentation here).
In a function if an argument is not used, it is only a "programming warning", nothing more. So the problem is that you use a parameter that may or may not be provided.
So this is handled using
nargin % the number of parameters provided in current call
nargin(function_name) % the number of parameters the declaration has
So based on these you may program some conditions and include there the code that uses the non-standard input parameters.
For more complex cases varargin is most proper that handles variable length parameter list where the ordering may not be defined. But this is too much for this question
Upvotes: 1
Reputation: 9157
The simplest way to do this is to use the nargin
variable:
function y = getValue(modelName,param,option)
open_system(modelName);
if (nargin < 3)
# No option passed, do something like
runModel('defaultOption')
else
# Option passed
runModel(option);
end
y = getActiveFun(param);
end
nargin
is just the number of input arguments that were actually submitted. Thus, nargin == 3
indicates that the option parameter has been set, nargin < 3
that it has not been set.
Thus, you could now always call your function like
result = getValue('myModel', myParameter)
or with all parameters
result = getValue('myModel', myParameter, someOption)
Upvotes: 7
Reputation: 518
Look at the following link:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/65943
they have several suggestions
Upvotes: 0