MATLAB: User-defined classes and support for ‘{}’ type linear indexing.

cell arraycomma separated list overloadingcurly bracketslinear indexingMATLABoopuser defined class

Dear all,
I overloaded subsref() and subsasgn() in a class that I built and I seem unable to reproduce the behavior that built-in types/classes, typically cell/struct arrays, have when linearly indexed with {} (this generalizes to any case of linear/mixed indexing with n subs on cell arrays with more than n dimensions). Here are a few tests to illustrate:
>> a = {3, 4} ;
>> a{:} % Comma separated list of elements
ans = % (cells content).
3
ans =
4
>> S = substruct( '{}', {':'} ) ; % Build S struct array.
>> subsref( a, S ) % Call class cell subsref().
ans = 3
>> builtin( 'subsref', a, S ) % Same, just in case.
ans = 3
>> b = a{:} % Single LHS => only first RHS saved.
b = 3
>> ans = a{:} % Special behavior with ans? No.
ans = 3
>> c = cell( numel(a), 1 ) ; % Matching LHS, RHS when we know
>> [c{:}] = a{:} % a priori the size of the block
c = % targeted by the sub.
[3]
[4]
>> ans, ans = a{1}, a{2} % Hand-made comma separated list
ans = % when we know a priori the size
3 % of the block targeted by the sub.
ans =
4
>> ans, ans = subsref( a, S ) % Even for built-ins, subsref()
ans = % outputs at most a cell array.
4 % <- this is the previous ans
ans = % <- this is the output of subsref()
3 % So a{:} is not managed by subsref(),
% but transformed into
% ans, ans = a{1}, a{2}
% by the interpreter that is able to
% manage linear indexing with {} for
% built-in classes only??
It seems to me that managing a{:} is not or cannot be done at the subsref() level as the method must output a cell array (varargout) and cannot output a comma separated list. Then, the way I understand the behavior above when using the syntax a{:}, is that the interpreter checks whether "a" is an instance of a built-in type/class (typ. cell and struct array), and if so is able to compute a priori the number of elements of a{:} and evaluate the following
ans, ans = a{1}, a{2}
If I am not too wrong, it is therefore not possible to build user-defined classes that are treated the same way by the interpreter (that cannot know a priori the size of the block being indexed)?, .. unless there is a way to tell MATLAB that instances of this user-defined class behave like built-ins, or some numel()-like method call including subs, that we could manage with an overload? What did I understand/misunderstand?
Thank you and best regards,
Cedric
(R2011b, 64-bit)

Best Answer

If you supply an overloaded numel() method then the problem should go away, as long as you're just trying to imitate cell arrays.
However, there are definitely limitations in overloading comma-separated lists when you use more deeply nested indexing. See this related thread for an expanded discussion