overloaded subsref and display vs. command line

1 view (last 30 days)
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

Answers (1)

Jacob Halbrooks
Jacob Halbrooks on 9 Mar 2012
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 Comments
Pieter van den Berg
Pieter van den Berg on 9 Mar 2012
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 on 9 Mar 2012
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.

Sign in to comment.

Categories

Find more on Argument Definitions 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!