User-defined classes and support for '{}' type linear indexing.

1 view (last 30 days)
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)
  2 Comments
Daniel Shub
Daniel Shub on 10 Jan 2013
Am I correct that this is only an issue with cell arrays? Are you basically trying to create a user defined cell array class?
Cedric
Cedric on 10 Jan 2013
Edited: Cedric on 10 Jan 2013
Daniel, you are correct. It is specific to managing indexing that is interpreted as something that should "generate" a comma separated list. I am creating a class that generalizes "arrays", and that should behave like cell arrays when built based on @cell.

Sign in to comment.

Accepted Answer

Matt J
Matt J on 10 Jan 2013
Edited: Matt J on 10 Jan 2013
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
  5 Comments
Matt J
Matt J on 10 Jan 2013
I'm glad it's working, though I urge you to read the link I gave you so that you're apprised of some of the general limitations of of {:} overloading.
Cedric
Cedric on 10 Jan 2013
I had found your question from 2009 with no answer before I wrote mine, but not the 2012 thread, which I fully read before updating my code. Thank you again!

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!