I have a class that assigns an immutable UUID to the object in its constructor. The following is a simplified illustration:
classdef mytest
properties (GetAccess = public, SetAccess = immutable)
uuid
end
properties
val
end
methods
function obj = mytest(valIn)
obj.uuid = char(java.util.UUID.randomUUID.toString);
if nargin < 1
valIn = 0;
end
obj.val = valIn;
end
end
end
This is working great in general, but I just discovered an issue with MATLAB's behaviour when assigning default elements to an array. I had assumed that if I typed
>> a(5) = mytest(2);
the constructor would be called 5 times - 4 times with no input arguments, to fill the default elements 1 to 4 of the array, and once with input argument 2 to assign the final element.
However, that's not what MATLAB does - instead it calls the constructor only once with no inputs, then copies the result four times to fill elements 1 to 4 (and then as expected for the final element). That means that the UUIDs ef elements 1 to 4 end up the same:
>> {a.uuid}'
ans =
'4424b91b-0977-4b4c-b18b-c4564875b952'
'4424b91b-0977-4b4c-b18b-c4564875b952'
'4424b91b-0977-4b4c-b18b-c4564875b952'
'4424b91b-0977-4b4c-b18b-c4564875b952'
'dbb8d862-8a1c-4bf9-876f-ef786e11a896'
It turns out this is documented behaviour that I just didn't expect, and I kind of understand why MathWorks have chosen to do that (you might not want the overhead of calling a no-input constructor many times separately).
But it's not the behaviour I want for this class - does anyone know of a way to force the constructor to be called for each element? Or perhaps you can suggest a different class design that would have the desired behaviour?
PS I did investigate whether MATLAB might be copying these default elements using a copy method - in which case inheriting my class from matlab.mixin.Copyable, and overriding the behaviour of copyElement might help - but it looks like that's not how it does the copying :(.
Disclaimer: I'm not too familiar with MATLAB classes.
Looking at the relevant docs it seems that you're doing everything right, and so is MATLAB:
a(1,7) = SimpleValue(7)The object assigned to array element
a(1,7)uses the input argument passed to the constructor as the value assigned to the property:...
MATLAB created the objects contained in elements
a(1,1:6)with no input argument. The default value for properties empty[]....
MATLAB calls the
SimpleValueconstructor once and copies the returned object to each element of the array.
This suggests that what you're experiencing is documented behaviour: automatic allocation of previously unassigned array elements is done with a single call to the constructor with zero input arguments.
This is also in agreement with another example using a random initializer: the example code uses
for k = 1:5
a(k) = ObjProp;
end
to set the 5 elements of the array such that they contain different random data. At least from the documentation, this seems to be the work-around for your problem: initializing each empty element by hand (which is probably not what you want to do).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With