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

10 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 =
2
>> y=p(x)
y =
26
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.
  4 Comments
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.
Matt J
Matt J on 12 Apr 2022
Edited: Matt J on 12 Apr 2022
I understand the danger of allowing indexing to call subsref from within another class method, but why should it be disallowed in class-related functions, which are external to the classdef? Using the example class definition below, it strikes me as strange that test_implem should raise an error when other external functions do not.
>> test(myclass)
Unrecognized method, property, or field 'p' for class 'myclass'.
Error in myclass>test_implem (line 18)
obj.p;
Error in myclass/test (line 11)
test_implem(obj);
classdef myclass
methods
function subsref(obj,subs)
disp 'Subsref called'
end
function test(obj)
test_implem(obj);
end
end
end
function test_implem(obj)
obj.p;
end

Sign in to comment.

More Answers (0)

Categories

Find more on Class Introspection and Metadata in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!