MATLAB: How to add a new element to an object array using pass by reference

callbackguiMATLABobjectsooppass by reference

Hello,
I am trying to use pass by reference using handle objects.
The scenario I have right now is I have an array of handle objects defined by:
classdef unit < handle
and I'd like to pass an array of such an object to a function which in turn sets a callback to a button that once pressed, should add a new element to that array. I have managed to pass the array through to the callback function. When I change the value of the properties of any of the original elements, the original array gets updated, as expected. However, when I add an element, the new element is lost when the callback function completes, as expected I suppose.
But since I cannot return anything from a callback, what method can I use to add this element and have it update the original object? A couple potential solutions I've thought of:
1. Do I need to pre-augment the array? But I do not know if I need to augment the array until the callback executes.
2. Do I have to create another handle class that is used simply to hold this "unit" object array in a pass by reference scenario? Seems awfully clunky to me.
Thanks in advance!

Best Answer

The documentation on Initialize Arrays of Handle Objects says "[...] Creates unique handles for each element in the array." I assume that explains the behaviour you see.
Another potential solution: Preallocate a large enough array. It doesn't require that much memory. And implement a mechamism to keeps track of the "current size" of the arryay. MWE:
>> object_array(1,12) = MyClass(-1);
>> add_MyClass_object( object_array )
>> add_MyClass_object( object_array )
>> add_MyClass_object( object_array )
>> [object_array.ID]
ans =
1 2 3 -1 -1 -1 -1 -1 -1 -1 -1 -1
>>
where
classdef MyClass < handle
properties
ID
end
methods
function this = MyClass( id )
if nargin == 0
this.ID = -1;
else
this.ID = id;
end
end
end
end
and
function add_MyClass_object( array )
nxt = find( [array.ID] == -1, 1, 'first' );
array(1,nxt).ID = nxt; %#ok<*NASGU>
end
Your "awfully clunky" approach is that something like this?
>> ac = ArrayContainer;
>> ac.add_object
>> ac.add_object
>> ac.add_object
>> [ac.object_array.ID]
ans =
1 2 3
where
classdef ArrayContainer < handle
properties
object_array (1,:) MyClass = MyClass.empty
end
methods
function add_object( this )
len = numel(this.object_array);
this.object_array(1,end+1) = MyClass(len+1);
end
end
end
Comment: When using approaches like these in real applications one will certainly encounter problems, which one didn't anticipate up front. Experiments are needed, e.g.
>> ac.object_array(2).ID = 200;
>> [ac.object_array.ID]
ans =
-1 200
>>
:-( What *** happened? )-:
Guess what this returns
%%

object_array(1,12) = MyClass(-1);
add_MyClass_object( object_array )
add_MyClass_object( object_array )
add_MyClass_object( object_array )
[object_array.ID] %#ok<*NOPTS>

%%
object_array(1,2).ID = 200;
[object_array.ID] %#ok<*NOPTS>
Conclusion: Don't try to outsmart Matlab!
/R2018b