Custom Argument Validation Function for NameValueArgs

14 ビュー (過去 30 日間)
David DeVries
David DeVries 2019 年 11 月 4 日
コメント済み: David DeVries 2021 年 1 月 30 日
While working on a project, I found an interesting error when using custom argument validation functions on name-value arguments. I constructed this contrived example class to demonstrate:
classdef Dog
properties
Name
HouseNumber = []
end
methods
function obj = Dog(Name, NameValueArgs)
arguments
Name (1,1) string
NameValueArgs.HouseNumber double {Dog.mustBeScalarOrEmpty(NameValueArgs.HouseNumber)}
end
obj.Name = Name;
if isfield(NameValueArgs, 'HouseNumber')
obj.HouseNumber = NameValueArgs.HouseNumber;
end
end
end
methods (Static = true)
function mustBeScalarOrEmpty(var)
if ~(isscalar(var) || isempty(var))
error('Not scalar nor empty.');
end
end
end
end
When the following is run:
dog1 = Dog("Test",'HouseNumber',23)
This error is produced:
Error using Dog
Invalid name-value argument 'HouseNumber'. Index exceeds the number of array elements (1).
I'm not understanding why this error is being triggered. Is it not valid to call a static method from the class as a custom argument validation function?

回答 (1 件)

Roshni Garnayak
Roshni Garnayak 2019 年 11 月 10 日
Try using ‘varargin’ in place of ‘NameValueArgs’. To validate the properties and assign values to them, use the ‘set’ method.
You can refer to the following link to get an idea of how to use Name-value pair arguments in constructor:
For further details on ‘varargin’ and ‘set’ method refer to the following links:
  3 件のコメント
Jan Kappen
Jan Kappen 2021 年 1 月 28 日
@Roshni Garnayak, are you really proposing varargin when the new argument validation features are that awesome?!
@David DeVries, your approach is much better imo. And in R2020b Update 2 it runs well:
>> dog1 = Dog("Test",'HouseNumber',23)
dog1 =
Dog with properties:
Name: "Test"
HouseNumber: 23
What happens if you move the validation function out of the classdef?
classdef Dog
properties
Name
HouseNumber = []
end
methods
function obj = Dog(Name, NameValueArgs)
arguments
Name (1,1) string
NameValueArgs.HouseNumber double {mustBeScalarOrEmpty(NameValueArgs.HouseNumber)}
end
obj.Name = Name;
if isfield(NameValueArgs, 'HouseNumber')
obj.HouseNumber = NameValueArgs.HouseNumber;
end
end
end
% methods (Static = true)
% function mustBeScalarOrEmpty(var)
% if ~(isscalar(var) || isempty(var))
% error('Not scalar nor empty.');
% end
% end
% end
end
% subfunction outside classdef!
function mustBeScalarOrEmpty(var)
if ~(isscalar(var) || isempty(var))
error('Not scalar nor empty.');
end
end
Maybe you can create a non-static validator that calls the class static one?
David DeVries
David DeVries 2021 年 1 月 30 日
@Jan Kappen: Glad to hear that the bug was fixed in MATLAB 2020b.
In the meantime I was using another class and defining "mustBeScalarOrEmpty" in a different class as a public static method, and it seemed to work.
In general, defining functions outside of a classdef breaks many object orientated programming rules, so I avoid that where I can.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeConstruct and Work with Object Arrays についてさらに検索

製品


リリース

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by