MATLAB Answers

Why is the SUBSREF method not called when used from within a method of a class?

15 views (last 30 days)
Using the polynomial class example in the documentation, I have created a class @polynom. Within this class, I have defined a number of methods, one of which is SUBSREF. When I call any overloaded method from within a method of the polynom class, I do not run into any problems. MATLAB knows to look in the class for the method first.
I then try to subsref into my object and instead of calling the overloaded SUBSREF, MATLAB attempts to call the built-in SUBSREF. To work around this I have to explicity call SUBSREF. I would like to know why this works for all other overloaded methods.
The following is an example of calling an object's subsref from the command line:
>> p = polynom([1 2 3 4])
p =
x^3 + 2*x^2 + 3*x + 4
>> x = 2
x =
>> y=p(x)
y =
When calling y = p(x) from an overloaded method called plot:
>> plot(p)
Warning: Subscript indices must be integer values.
> In p:\@polynom\plot.m at line 10
??? Index into matrix is negative or zero. See release notes on changes to
logical indices.
Error in ==> p:\@polynom\plot.m
On line 10 ==> y = p(x);
To workaround this, I have to call SUBSREF explicitly:
y = polyval(p,x);
subs.type = '()';
subs.subs = {x};
y = subsref(p, subs); %should call subsref here

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 27 Jun 2009
This is working as it was designed. The documentation was fixed to explain this behavior in MATLAB 7.1 (R14SP3). For a detailed explanation or if you are using versions before MATLAB 7.1, read below:
Whenever a class method requires the functionality of the overloaded SUBSREF, it must call the overloaded SUBSREF using the function call to SUBSREF rather than using SUBSREF operators like '()', '{}', '.' etc.
Although this behavior may appear inconsistent when compared to other methods, it is in fact provided in order to prevent erroneously entering a state where the the SUBSREF method ends up calling itself thereby ending up in an endless loop.
The same is true for SUBSASGN.
Steven Lord
Steven Lord on 31 Mar 2020
Getting into an infinite loop is always a danger. But if we allowed indexing to call subsref from inside a class method, it would be very easy to get into an infinite loop. Disallowing implicitly calling subsref reduces the chances of accidentally looping.
As the Support Team's answer states, if you explicitly call subsref inside your class methods you get the overloaded method. It's only the operator forms that bypass the overloaded subsref. So you can deliberately invoke the method if you know what you're doing.

Sign in to comment.

More Answers (1)

Guillaume Marrakchi
Guillaume Marrakchi on 15 Dec 2016
Edited: Guillaume Marrakchi on 15 Dec 2016
Is there an update on this question since 2015?
Isn't there a way to force the usage of the class-defined subsref, instead of the default one (without having to use the full notation subsref(obj, s)) ? What is the purpose of letting people overload subsref if it's impossible to use it with the () / {} / '.' notation later on ?!
I have a 'long' subsref expression, embedded in a class method, like :
MyObjects([1,5,6:10]).myMethod(arg1, arg2)
Here, length(s) = 3, and it would be quite cumbersome to have to define the structure s from scratch, just to be able to use subsref(MyObjects,s). Especially if this operation is needed several times with different arguments each time... It would mean defining:
s(1).type = '()';
s(1).subs = {[1,5,6:10]};
s(2).type = '.';
s(2).subs = 'MyMethod';
s(3).type = '()';
s(3).subs = {arg1, arg2};
subsref(MyObjects, s)
everytime I want to apply methods/properties to vectorized objects...
Any suggestion ? (arrayfun is not a satisfactory answer, and I don't want either to abandon the dot notation to call the class methods)

Community Treasure Hunt

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

Start Hunting!