Overloading of subsref partially failing

4 views (last 30 days)
Sven on 27 Oct 2016
Commented: Sven on 28 Oct 2016
I want to create an array class of generic dimensions. So I wanted to overload the subsref indexing. Worked mostly on first sight, now encounter strange behavior, as shown in this minimal example:
ThisArray = MyArray;
ThisArray(:) % <---- This works fine
ThisArray(:) % <---- This works fine
classdef MyArray < handle
function obj = MyArray
obj.MainArray = [1 2; 3 4];
end % function MyArray
function sref = subsref(obj,s)
switch s(1).type
case '()'
sref = obj.MainArray(s(1).subs{:});
sref = builtin('subsref',obj,s);
end % switch
end % function subsref
function obj = ChangeArray(obj)
obj.MainArray(1) = obj.MainArray(1)+1;
obj(:) % <------ This one only displays object
NewArray = MyArray;
NewArray(:) % <------ This one only displays object
end % function ChangeArray
Running this from Main works fine in Main both marked occurrences output the MainArray as wanted. But when I call ChangeArray the subsref overload does not work anymore. Both tries to use the overloaded indexing just outputs the object, indicating the my overloaded subsref is not reacting and (:) is just ignored. Breakpoint on switch in subsref shows no entering of this function on both problematic occasions.
Why can't I use those indices within this object method.
P.S.: I liked the handle inheritance for my class, but removing it did not appear to make a difference.
Thanks for any help.

Accepted Answer

Matt J
Matt J on 27 Oct 2016
Edited: Matt J on 27 Oct 2016
SUBSREF is not triggered by index expressions inside a classdef file. Inside the classdef, you have to call subsref explicitly if you want it to execute:
function obj = ChangeArray(obj)
obj.MainArray(1) = obj.MainArray(1)+1;
NewArray = MyArray;
end % function ChangeArray
This is meant to allow you to use index expressions inside the subsref method without them triggering an infinite chain of recursive calls to the subsref method itself.
  1 Comment
Sven on 28 Oct 2016
Thanks for the answer. Makes sense to avoid that possible recursion. Seems to be obvious after you said it.

Sign in to comment.

More Answers (1)

Steven Lord
Steven Lord on 27 Oct 2016
See the "Built-In subsref and subsasgn Called in Methods" section on this documentation page.
If you want to invoke an overloaded subsref or subsasgn method inside a method you must do so explicitly by calling subsref(...) or subsasgn(...).
You cannot invoke those overloaded indexing methods implicitly by indexing into the object using parentheses like obj(1), curly braces like obj{2}, or dot referencing like obj.prop1.

Community Treasure Hunt

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

Start Hunting!