I have written a Matlab R2020b function that optionally receives three inputs - but if the inputs are not received, they should be set to the defaults within the script.
function my_opt_func(opt1, opt2, opt3)
if (~exist(opt1, 'var'))
opt1 = setopt1();
end
if (~exist(opt2, 'var'))
opt2 = setopt2();
end
if (~exist(opt3, 'var'))
opt3 = setopt3();
end
disp(string(opt1) + string(opt2) + string(opt3))
function opt1 = setopt1()
opt1 = 1;
end
function opt2 = setopt2()
opt2 = 2;
end
function opt3 = setopt3()
opt3 = 3;
end
end
Here, the different setopt
functions are used to generate the appropriate default values.
Unfortunately, calling this function without parameters, as my_opt_func
or my_opt_func()
gives the error Not enough input arguments
. I tried using a variant of varargin
, but got the same error.
When I set the values without using the setopt
functions, I don't get this error - but due to the complexity of my actual program, I really need to use functions to develop my defaults.
How do I fix this error so that the user can call the function with or without parameters - as either my_opt_func()
or my_opt_func(param1, param2, param3)
?
Cris answered your direct question in the commments, exist
expects you to input the name of the variable, not the variable itself (since it might not exist!)
if (~exist('opt1', 'var')) % <- char 'opt1' is the variable name
opt1 = setopt1();
end
But there are some slightly nicer ways to do this anyway, the syntax for calling your function would be the same in all cases.
nargin
(number of arguments input). Since this is directly dependent on the number of input arguments, you can't do something like accidentally define the variable above your input validation and breaking the flow.function my_opt_func(opt1, opt2, opt3)
if nargin < 1
opt1 = setopt1();
end
if nargin < 2
opt2 = setopt2();
end
if nargin < 3
opt3 = setopt3();
end
...
addOptional
means you can keep the function calling syntax the same. Alternatively you could use the input parser for name-value pairs. I find this is often overkill unless you want to utilise the other functionality inputParser
offers.function my_opt_func(varargin)
p = inputParser;
p.addOptional( 'opt1', setopt1() );
p.addOptional( 'opt2', setopt2() );
p.addOptional( 'opt3', setopt3() );
p.parse( varargin{:} );
opt1 = p.Results.opt1;
opt2 = p.Results.opt2;
opt3 = p.Results.opt3;
...
arguments
syntaxfunction my_opt_func(opt1, opt2, opt3)
arguments
opt1 double = setopt1()
opt2 double = setopt2()
opt3 double = setopt3()
end
...
Note that inputParser
will run the setoptx
functions for the default values regardless if values have been passed in, but the arguments
syntax is more efficient since the setoptx
functions will only be evaluated if the input isn't given.