Why can't I use builtin for classes that overload subsref?

3 views (last 30 days)
It seems like Matlab's 'builtin' function doesn't work when subsref is overloaded in a class. Consider this class:
classdef TestBuiltIn
properties
testprop = 'This is the built in method';
end
methods
function v = subsref(this, s)
disp('This is the overloaded method');
end
end
end
To use the overloaded subsref method, I do this:
t = TestBuiltIn;
t.testprop
>> This is the overloaded method
That's as expected. But now I want to call Matlab's built in subsref method. To make sure I'm doing things right, first I try out a similar call on a struct:
x.testprop = 'Accessed correctly';
s.type = '.';
s.subs = 'testprop';
builtin('subsref', x, s)
>> Accessed correctly
That's as expected as well. But, when I try the same method on TestBuiltIn:
builtin('subsref', t, s)
>> This is the overloaded method
...Matlab calls the overloaded method rather than the built in method. Why does Matlab call the overloaded method when I requested that it call the builtin method?

Accepted Answer

Matt J
Matt J on 24 Apr 2013
Edited: Matt J on 24 Apr 2013
I'm guessing a bit, but in MATLAB there are certain precedence rules for choosing which versions of functions can apply to a given list of input arguments. I think BUILTIN can only choose between functions that are of equal precedence (other than w.r.t. position on the path, of course).
In your case, you are calling builtin('subsref',...) with an object, t, of a user-defined class testBuiltIn, as an input argument. Under the precedence rules, user-defined class methods dominate everything but subfunctions, so the only versions of subsref that are of equal precedence are those belonging to the TestBuiltIn class. MATLAB's builtin subsref is not a method of TestBuiltIn, so it is ignored by builtin('subsref',t,s).
It might be worth talking to Tech Support to see if this is intended behavior.
  6 Comments
Matt J
Matt J on 24 Apr 2013
Edited: Matt J on 24 Apr 2013
Both test1 and test2 return 'This is the overloaded method'.
Nope. This is what I get,
>> test1(t)
ans =
This is the built in method
>> test2(t)
ans =
This is the built in method
I'm guessing that you used the following syntax instead, but these expressions do not genuinely invoke test1() and test2().
>> t.test1
ans =
This is the overloaded method
>> t.test2
ans =
This is the overloaded method
Again, because you executed these expressions outside the class, they were never interpreted as calls to test1 and test2. They were interpreted as indexing expressions and went straight to the class's subsref, just like this does:
>> t.CatsAndDogs
ans =
This is the overloaded method
Ben
Ben on 24 Apr 2013
because you executed these expressions outside the class, they were never interpreted as calls to test1 and test2. They were interpreted as indexing expressions and went straight to the class's subsref
Ah, exactly right. Thanks for that clarification. I've never used the method(instance) syntax rather than instance.method syntax so I didn't quite put it together that they would behave so differently. But your explanation is very clear.

Sign in to comment.

More Answers (1)

Matt J
Matt J on 24 Apr 2013
Edited: Matt J on 24 Apr 2013
The problem is that subsref doesn't actually work like before. Consider this:
It's only because the programming logic in subsref is wrong. Here's a better version
function v = subsref(this, s)
if strcmp(s(1).type, '.') && strcmp(s(1).subs, 'child')
s=s(2:end);
if ~isempty(s)
v=subsref(this.child, s);
else
v=this.child;
end
elseif strcmp(s(1).type, '()')
v = 'overloaded method';
else
v=builtin('subsref',this,s);
end
end

Products

Community Treasure Hunt

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

Start Hunting!