overloaded subsref and display vs. command line

1 次查看(过去 30 天)
Hi,
when I overload subsref in a class, I can explicitly call the builtin subsref to get to the methods and properties of the class. Since I don't know the number of output arguments beforehand I use varargout, for instancce in this simple example
classdef myClass
properties
name = 'test'
end
methods
function varargout = subsref(obj, s)
varargout = cell(1,nargout);
[varargout{:}] = builtin('subsref',obj,s);
end
end
end
This works fine with assignments, eg. calling
c = MyClass;
a = c.name;
or when calling a method with no output arguments.
What doesn't seem to work as expected is calling a property in an unterminated statement on the commandline:
>> c.name
??? The left hand side is initialized and has an empty range of indices.
However, the right hand side returned one or more results.
Error in ==> myClass>myClass.subsref at 8
[varargout{:}] = builtin('subsref',obj,s);
Hoever, calling display explicitly causes no error:
>> display(c.name)
test
Explicitly checking the number of output arguments, ie.
function varargout = subsref(obj, s)
if nargout > 0
varargout = cell(1,nargout);
[varargout{:}] = builtin('subsref',obj,s);
else
builtin('subsref',obj,s);
end
end
instead produces no output on the commandline call,
>> c.name
>>
whereas display(c.name) works as before.
I know this is perhaps a minor annoyance but I'd like to understand it anyway, if anyone has an explanation.
cheers, Pieter

回答(1 个)

Jacob Halbrooks
Jacob Halbrooks 2012-3-9
When you call "disp(c.name)", you are explicitly requesting an output argument from c.name and as a result NARGOUT returns 1 in your SUBSREF method. This is equivalent to doing this:
myName = c.name;
disp(myName);
However, when you execute "c.name", there is no output argument requested, and as a result NARGOUT is 0 in your method, causing the error. The display from leaving off the semi-colon is actually on the ANS variable. This case is then equivalent to doing this:
c.name;
disp(ans);
I think your solution might be to always return a minimum of 1 argument to ensure that ANS gets populated:
function varargout = subsref(obj, s)
varargout = cell(1,max(1,nargout));
[varargout{:}] = builtin('subsref',obj,s);
end
  2 个评论
Pieter van den Berg
Jacob, thanks for your answer.
This would indeed solve the problem of displaying properties but then calling a method that returns zero arguments on the command line would now give a 'Too many output arguments' error.
Jacob Halbrooks
Jacob Halbrooks 2012-3-9
You are right. It seems the root problem is that NARGOUT reports 0 for both the case where ANS can be assigned and for the method call (which as you point out throws an error if you try to assign an output). I cannot think of a test to differentiate the two cases. I suppose a TRY/CATCH might be helpful if it's important to handle both cases.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Software Development Tools 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by