Function Argument Validation from Class Properties ignores defaults
5 次查看(过去 30 天)
显示 更早的评论
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.
0 个评论
采纳的回答
Aghamarsh Varanasi
2021-3-9
编辑:Aghamarsh Varanasi
2021-3-9
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
更多回答(1 个)
Youssif Mosa
2023-3-31
编辑:Youssif Mosa
2023-3-31
Version 2022a still does not have this feature :(
I do not know about later versions but here is an elegant refactor for the same answer from @Aghamarsh Varanasi
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
fromclass=autoFillDefaults(fromclass,?DefineArg); % Just add this line after the arguments block
% show
local % default available
fromclass % now this also have default values
end
The function autoFillDefaults() can be in a separate file for reuse, you will need to add just one like after the arguments block.
This function will autofill the default values only for the arguments not provided on the function call.
function fromclass = autoFillDefaults(fromclass,metaClass)
arguments
fromclass struct
metaClass meta.class
end
p=metaClass.PropertyList;
for n=1:length(p)
if p(n).HasDefault && ~isfield(fromclass,p(n).Name)
fromclass.(p(n).Name)=p(n).DefaultValue;
end
end
end
1 个评论
Aliasghar
2024-10-7
unfortunately, this only works when the default vlue is assigned to the property of the superclass. Not if the default value is only defined in the arguments block of the constructor or static method(s).
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Class File Organization 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!