Type conversion happens before matlab Set method is called in classes, problem with setting int64(Nan) = [] default is 0

2 views (last 30 days)
I am trying to set the default behaviour of a class so that int64(NaN) is set to empty and Not to the default 0.
Here is a simple class example class example:
classdef TestClass < matlab.mixin.SetGet
% CLASSDEF TestClass class to test add NaN
%
properties
a int64 {mustBeNonNan} = []
end % methods
methods
function obj = TestClass()
end % TestClass
function set.a(obj, val)
disp(val)
class(val)
obj.a = val;
end
end % methods
end % class
If you try and set a = Nan here it gets set to 0, in the set method it is already a int64 and not a double NaN. Is there a way to change this? I don't really want to addListeners and handle preSet methods. I also want the class type to be an int64 rather than not give it a type and then set the type in the set method.
On another note why is int64(NaN) set to 0 anyway?
This would work, but then the class property would not be an int64.
classdef TestClass < matlab.mixin.SetGet
% CLASSDEF TestClass class to test add NaN
%
properties
a
end % methods
methods
function obj = TestClass()
obj.a = int64([]);
end % TestClass
function set.a(obj, val)
if isnan(val), val = []; end
obj.a = int64(val);
end
end % methods
end % class
  4 Comments
Matt J
Matt J on 28 Nov 2022
I also want the class type to be an int64 rather than not give it a type and then set the type in the set method.
I don't see why you would prefer that. One is just a shorthand for the other.
Benjamin Klein
Benjamin Klein on 28 Nov 2022
Thank you for the answers, it's a good point about arrays, guess why int64(NaN) becomes a zero. In this case it's a singular value so in my class I define:
a(1,:) int64 = []
So that isn't a problem for me. It would be best to just leave it untyped and deal with that in the set method, the running code won't change, my problem with this is that only when users looks at the object they won't know what type of variable they have to set it to such as:
myclass with properties:
a: [1×0 int64]
b: [1×0 string]
c: [1×0 string]
I am really intested in the subsasgn answer (below) because Matlab treats that differently so that it doesn't evaluate val before it reaches the subsasgn method. Following various help files I found an example to create your own type int64p:
classdef int64p < int64
methods
function obj = int64p(data)
if nargin < 1, data = int64([]); end
data(isnan(data)) = [];
obj = obj@int64(data); % Store data on superclass
end
end
end
So I define my own version of int64 as int64p and then I can have my class as:
classdef myclass < matlab.mixin.SetGet
% CLASSDEF myclass class to test add NaN
%
properties
a(1,:) int64p = []
b(1,:) string = []
c(1,:) string = []
end % methods
methods
function set.a(obj, val)
if isnan(val), val = []; end
obj.a = int64(val);
end
end % methods
end % class

Sign in to comment.

Answers (2)

Matt J
Matt J on 28 Nov 2022
One possibility:
>> obj=myclass; obj.a=1:5, obj.a(2)=nan
obj =
myclass with properties:
a: [1 2 3 4 5]
obj =
myclass with properties:
a: [1 3 4 5]
classdef myclass < matlab.mixin.SetGet
% CLASSDEF TestClass class to test add NaN
%
properties
a
end % methods
methods
function set.a(obj, val)
val(isnan(val))=[];
obj.a = int64(val);
end
function val=get.a(obj)
val=double(obj.a);
end
end % methods
end % class

Matt J
Matt J on 28 Nov 2022
Another approach, using subsasgn(). This one avoids conversion of obj.a to double.
>> obj=myclass; obj.a=1:5, obj.a(2)=nan
obj =
myclass with properties:
a: [1 2 3 4 5]
obj =
myclass with properties:
a: [1 3 4 5]
classdef myclass < matlab.mixin.SetGet
% CLASSDEF TestClass class to test add NaN
%
properties
a int64
end % methods
methods
function obj=subsasgn(obj,S,val)
obj=builtin('subsasgn',obj,S,val);
if strcmp(S(1).type,'.') && strcmp(S(1).subs,'a')
b=false(size(obj.a));
if numel(S)>1
b(S(2).subs{:})=isnan(val);
else
b=isnan(val);
end
obj.a(b)=[];
end
end
end % methods
end % class

Categories

Find more on Argument Definitions in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!