How do I use a class property validation function with a dynamic argument?

In Matlab OOP, I wanna use a function like mustBeEqualSize(a,b) from the Examples on function property validation to validate a property:
classdef foo
properties
a
b {mustBeEqualSize(a,b)}
end
end
However, this gives me an error.

 Accepted Answer

The problem is, that MATLAB classes only support constant arguments on property validation.
However function arguments can be validated perfectly fine with dynamic arguments.
So a workaround is to validate the arguments of the constructor:
classdef Foo
properties
a
b
end
methods
function obj = Foo(a,b)
arguments
a
b {mustBeEqualSize(a,b)}
end
obj.a = a;
obj.b = b;
end
end
end

4 Comments

This doesn't seem to be true with the mustBeMember function.
When I try to validate an input argument against a constant property of my class I get the following error
Example code:
classdef ContinuousSweep < handle
Class name and filename must match.
properties (Constant)
possibleResults = {'RMS Level','Gain','Phase','THD Ratio','THD Level','THD+N Ratio','THD+N Level','Impulse Response'}
end
methods
function obj = addPrimaryResult(obj,result)
%addPrimaryResult Adds a result of the specified type if it is allowed for this measurement type.
arguments (Input)
obj
result string {mustBeMember(result,obj.possibleResults)} % HERE it complains
end
disp(result)
end %addPrimaryResult
end
end
I want to reuse this string array as an argument validation parameter in multiple methods and "hard coding" it seems as a bad practice. Is there any solution to this?
Commenting because I have the exact same problem (granted, I'm attempting to do it with a dependent property rather than a constant property, but still).
I hope there's a working solution soon.
One thing that does half the job is overloading the ismember function for your class. Something like the following. I say half the job, because it "works" in the way you want, but it does not offer autocomplete (no popup with 'RMS Level', 'Gain', etc. will appear when you try to call obj.addPrimaryResult()).
methods
function boolOut = ismember(val, obj)
boolOut = ismember(val, obj.possibleResults);
end
end
Try this:
classdef ContinuousSweep < handle
properties (Constant)
possibleResults = {'RMS Level','Gain','Phase','THD Ratio','THD Level','THD+N Ratio','THD+N Level','Impulse Response'}
end
methods
function obj = addPrimaryResult(obj,result)
%addPrimaryResult Adds a result of the specified type if it is allowed for this measurement type.
arguments (Input)
obj
result string {mustBePossibleResult(result)}
end
disp(result)
end %addPrimaryResult
end
end
function mustBePossibleResult(result)
PR = ContinuousSweep.possibleResults;
assert(ismember(result, PR), ...
result + " must be one of: " + newline + strjoin(PR, ", "))
end
You can reuse mustBePossibleResult in multiple methods, as a locally defined validation function. If the property is not Constant (and so you need to retrieve the value from the instance rather than from the class) you may need to include obj in the argument list of mustBePossibleResult but since that's a previous input argument that's okay. Then you could get obj.possibleResults inside mustBePossibleResult.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2020b

Tags

Community Treasure Hunt

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

Start Hunting!