Clean way of integrating argument-handling with old code (struct vs. key-val pair with "arguments" keyword)
5 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
James
am 12 Mär. 2024
Beantwortet: Jacob Mathew
am 1 Apr. 2024
Our existing analysis pipeline (pre-R2019b) often configures options for various functions by passing a struct whose field names are the names of the options (those fields then holding the value for that option). This would be followed-up by a series of if(~isfield( commands to set the default cases, so something like this:
function myfunc(main_arg,optional_arg_struct)
if(~isfield(optional_arg_struct,'option1'))
optional_arg_struct.option1 = 'some_default';
end
...
We've recently moved our pipeline to a newer version of Matlab, so I'd like to make use of the arguments feature introduced in R2019b in writing my new functions, but have them be backwards-compatible with options passed in our "old" way. If I pass such a struct to a function using the arguments keyword, rather than key-value pairs, I get
Error using myfunc (line 1)
Invalid argument at position 2. Function requires exactly 1 positional input(s).
A workaround I've found is to provide three arguments, where the second is our old-style optional_arg_struct and the third is the arguments-style set of key/value pairs. In the arguments block, I basically ignore optional_arg_struct (just pass it as-is) and then have to manually jam the two of them together after the conclusion of the arguments block. But this is so clunky as to completely subvert the benefit of using the arguments functionality. Some extra conditionals/parsing prior to the arguments block could also achieve what I want, but it seems that the arguments syntax doesn't support that.
Is there any (clean) way of achieving what I want?
0 Kommentare
Akzeptierte Antwort
Jacob Mathew
am 1 Apr. 2024
Going through your query, it is difficult to reproduce the error without reference to the code that you are using in your new approach.
Meanwhile, a possible workaround that would be to use “varargin” and check if the first variable parameter is a struct or a string. Based on that you can decide to go with the older or newer workflow. An example of this is below:
function func(main_arg,varargin)
arguments
main_arg % main_arg conditions & validation can done here
end
arguments(Repeating)
varargin
end
if(isstruct(varargin{1}))
% you have passed a struct as the first optional argument
% Assuming that all key value pairs are within the struct,
% check for the missing keys and add their default values below
optional_arg_struct = varargin{1};
if(~isfield(optional_arg_struct,'option1'))
optional_arg_struct.option1 = 'some_default';
end
else
% you did not pass a struct, which means there are going to be name
% value pairs within the varargin. You can read those using a loop
% as follows
defaultStruct = struct('option1','some_default');
if mod(length(varargin), 2) ~= 0
error('Parameters should be in key-value pairs');
end
for k = 1:2:length(varargin)
% If the varargin contains a field, then we replace the structs
% default value with the one passed in the varargin
if isfield(defaultStruct, varargin{k})
defaultStruct.(param) = varargin{k + 1};
else
error('Unknown parameter name: %s', varargin{k});
end
end
end
end
0 Kommentare
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Structures finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!