필터 지우기
필터 지우기

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

조회 수: 2 (최근 30일)
Ben
Ben 2013년 4월 24일
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?

채택된 답변

Matt J
Matt J 2013년 4월 24일
편집: Matt J 2013년 4월 24일
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
Matt J
Matt J 2013년 4월 24일
편집: Matt J 2013년 4월 24일
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 2013년 4월 24일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Matt J
Matt J 2013년 4월 24일
편집: Matt J 2013년 4월 24일
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

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by