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.

채택된 답변

Aghamarsh Varanasi
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
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
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 CenterFile Exchange에서 Class File Organization에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by