overloaded subsref and display vs. command line

1 visualización (últimos 30 días)
Pieter van den Berg
Pieter van den Berg el 9 de Mzo. de 2012
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

Respuestas (1)

Jacob Halbrooks
Jacob Halbrooks el 9 de Mzo. de 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 comentarios
Pieter van den Berg
Pieter van den Berg el 9 de Mzo. de 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 el 9 de Mzo. de 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.

Iniciar sesión para comentar.

Categorías

Más información sobre Software Development Tools en Help Center y File Exchange.

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by