checking dataType instead typecast at property or argument validation
9 views (last 30 days)
Show older comments
Florian Osterloh
on 11 Feb 2020
Commented: per isakson
on 29 Feb 2020
Hello, I would like to use property/ argument validation in a different way. I would like to prevent the assignment of other types as the specified meta.Validation.Class.
As an example:
I've the following class
classdef TestPropertyValidation
properties
myProperty double {mustBeNumeric}
end
methods
function obj = TestPropertyValidation(stringVal)
obj.myProperty = stringVal;
end
end
end
If I pass now ...
>> TestPropertyValidation("Hello")
ans =
TestPropertyValidation with properties:
myProperty: NaN
I guess because of the conversion:
>> double("Hello")
ans =
NaN
>> isnumeric(NaN)
ans =
logical
1
But I like the way specifying conditions for properties. And I would like to use it in a bigger project. There we have to make sure no uncontrolled conversions happen between object constructor calls with lots of paramters passed to constructors and methods. I would like to prevent that for example 1+'1' := 50 operations can happen because of a misplaced method parameter for example.
I know I can use the ValidatorFunctions to prevent that for example a character is passed instead a double but only if I don't state the desired class, for example 'double' to don't have a conversion. It would be very nice having the type check and afterwards the validatorFunctions for further conditions to values. Is there a way to change the validation of properties and arguments to have a validation of the class instead of a conversion at validation order step 1.
Thank you.
0 Comments
Accepted Answer
Sean de Wolski
on 11 Feb 2020
There's no way to do this with validators in R2019b and the datatype coercion will always happen. You can use a set.property setter method to type check new values.
0 Comments
More Answers (3)
Hank
on 11 Feb 2020
Hi Florian,
I recently learned this property validation as well, and its been working for me.
Your syntax is backwards, if you're using {mustBeNumberic} you don't have to specify double. In fact, the double delcaration seems to be overwriting the metaclass validator. I tried your code with:
classdef TestPropertyValidation
properties
myProperty {mustBeNumeric}
end
methods
function obj = TestPropertyValidation(stringVal)
obj.myProperty = stringVal;
end
end
end
and got
>> test = TestPropertyValidation("hello")
Error using TestPropertyValidation (line 7)
Error setting property 'myProperty' of class 'TestPropertyValidation':
Value must be numeric.
>> test = TestPropertyValidation('word')
Error using TestPropertyValidation (line 7)
Error setting property 'myProperty' of class 'TestPropertyValidation':
Value must be numeric.
>> test = TestPropertyValidation([1 2 3 4])
test =
TestPropertyValidation with properties:
myProperty: [1 2 3 4]
0 Comments
Steven Lord
on 11 Feb 2020
If you specify both a property validator function and a class name, I believe MATLAB will cast the property name you try to set to that class before calling the property validator functions. In the "Using Validation Functions" section on this documentation page it states "Because the Data property validation does not include a numeric class, there is no conversion of the char vector to a numeric value. If you change the validation of the Data property to specify the class as double, MATLAB converts the char vector to a double array." and then "The assignment to the char vector does not produce an error because MATLAB converts the char vector to class double."
As the example in that section shows, if you don't include a class name MATLAB won't have anything to cast the property value to before it calls the property validator function.
If you want to restrict the property values even further, not just requiring them to be numeric but requiring them to be double, you could write your own local validator function similar to mustBeNumeric. You could call it mustBeDouble. See the "Define Validation Functions" section on that documentation page for an example you could use as a model
4 Comments
Jan Tusch
on 18 Feb 2020
IMHO, it isn't getting any better by documenting this counterinituitive behavior. When I first learned about this feature I was really happy to be able to express some type conventions to the user of my class. Thereby, making it really speaking code in the spirit of an interface definition. That said, I would expect the "validation" to do just what it is named after: validate the value beeing set to conform to my constraints.
However, all the magic under the hood performing conversion and scalar expansion renders this feature complete unsave (in the sense of an interface description), anyone can assign anything to my property als long as it is convertible. It makes sure the value conforms to my constraints by fiddling around to make it match.
Who in the world needs scalar expansion in an assignment? Use the colon. This is just a temptation to write sloppy code.
What is the benefit of this "validation" feaure in the first place?
The intention should not be to make even the sloppiest assignment convert to my constraints. The intention should be to inform the assignee that he violates my constraints.
Here are some goodies:
classdef SomeClass
properties
x (1,4) double
end
end
>> obj = SomeClass
obj =
SomeClass with properties:
x: [0 0 0 0]
>> obj.x = 2
obj =
SomeClass with properties:
x: [2 2 2 2]
>> obj.x = "a"
obj =
SomeClass with properties:
x: [NaN NaN NaN NaN]
>> obj.x = "0"
obj =
SomeClass with properties:
x: [0 0 0 0]
>> obj.x = '0'
obj =
SomeClass with properties:
x: [48 48 48 48]
>> obj.x = '01'
Error setting property 'x' of class 'SomeClass':
Size of value must match specified dimensions 1×4 or be scalar.
See Also
Categories
Find more on Argument Definitions in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!