Function Argument Validation from Class Properties ignores defaults

13 views (last 30 days)
This question is about function argument validation, based on the structname.?ClassName synthax as provided by Mathworks here. We're running R2020b - 9.9.0.1467703 (aug 2020, so I suspect 'Update 0'). First off, let me say I am a huge fan of the Arguments block, thank you so much Mathworks!
Context: we have multiple functions that at some point pass inputs to a set of classes with particular options. The intention is to define the name-value pairs once, and reuse that definition. This is opposed to copy-pasting parts of an arguments block, with the associated validation functions and defaults. Much neater to define once, and prevent a mess of different defaults, validations and such small differences. It also makes it much easier to update the whole family of function.
Issue: So we've defined one class to carry these options, their validation and defaults. Unfortunately the defaults appear not to be pass from the class defining the name-value paris.
Example code
file: TestInput.m
function TestInput(local, fromclass)
arguments
local.one (1,1) double = pi
local.two (1,:) char {mustBeMember(local.two, {'a', 'bb', 'ccc'})} = 'ccc'
fromclass.?DefineArg % crucial part where name-values are pulled from classdef
end
% show
local % default available
fromclass % no defaults available, despite class defining them
end
file: DefineArg.m
classdef DefineArg
properties
Exquise (1,1) double {mustBeNonnegative, mustBeInteger} = 3
Expletive (1,:) char {mustBeMember(Expletive, {'ai', 'caramba'})} = 'caramba'
end
end
Running the following code gives an empty fromClass struct:
Question: any way to also get the defaults? So far we get the name, size, class, validation but not the defaults!? I suppose you often don't want this, but it might be really nice to be able to turn this on.
ps: note how nicely the autocomplete works, including the valid inputs.

Accepted Answer

Aghamarsh Varanasi
Aghamarsh Varanasi on 9 Mar 2021
Edited: Aghamarsh Varanasi on 9 Mar 2021
Hi,
As of R2020b, meta class operator '?' can be used to validate function arguments. It does not support assignment of default arguments from meta.class. As a work-around you can assign the default values of the meta.class arguments to the function arguments after the validation as follows.
function TestInput(local, fromclass)
arguments
local.one (1,1) double = pi
local.two (1,:) char {mustBeMember(local.two, {'a', 'bb', 'ccc'})} = 'ccc'
fromclass.?DefineArg % crucial part where name-values are pulled from classdef
end
if isempty(fields(fromclass)) % ensure fromclass is empty
% assign default values to name-value pairs
metaClass = metaclass(DefineArg);
for i = 1:numel(metaClass.PropertyList)
prop = metaClass.PropertyList(i);
if prop.HasDefault
fromclass.(prop.Name) = prop.DefaultValue;
end
end
end
% show
local % default available
fromclass % no defaults available, despite class defining them
end

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!