Problem with nargout inside a constructor

6 次查看(过去 30 天)
I have a problem with the function nargout when used inside a constructor. For example, let us first create a basic function as follows:
function obj = payment(r,t)
nargout
obj.rate = r;
obj.term = t;
end
With the call payment(1,2), the function nargout returns 0, which is the expected answer.
Assume now that payment is a constructor:
classdef payment
properties
rate;
term;
end
methods
function obj = payment(r,t)
nargout
obj.rate = r;
obj.term = t;
end
end
end
With the same call payment(1,2), the function nargout returns 1, which is unexpected as I did not ask for an output argument.
So here are my questions:
  • Is there a bug in the function nargout or is there a good reason why I get such a behavior?
  • How can I know inside a constructor the exact number of output arguments requested by the user?
Thank you!
  2 个评论
Guillaume
Guillaume 2014-11-26
This is probably due to the way Mathworks has implemented classes in matlab. Sometimes, that implementation feels a bit hacked together. Here is probably a case where it shows.
However, a constructor can only have one output argument, the object being constructed. So why would you want to use nargout?
Clément
Clément 2014-11-26
编辑:Clément 2014-11-26
The Matlab code in my initial message was just to illustrate what happens when nargout is used inside a constructor.
If the user does not specify any output argument (e.g. payment(1,2) ), then the result will only be stored in the variable ans. I would like to detect this and store the result in a variable whose name varname is fixed inside the constructor.
classdef payment
properties
rate;
term;
end
methods
function obj = payment(r,t)
obj.rate = r;
obj.term = t;
if nargout==0
assignin('caller','varname',obj);
end
end
end
end
But the problem is that nargout always returns 1!

请先登录,再进行评论。

回答(1 个)

Guillaume
Guillaume 2014-11-26
As I said, it's probably a case where the implementation details of the class system is showing through the cracks, so there's probably nothing you can do.
More importantly, your idea sounds ill conceived. It's never a good idea to go behind the user's back or try to second guess what they're doing.
If they didn't ask for the return value to be stored, that's their choice. Forcing it on them in an unexpected way is not the right approach. Particularly, since you may be overwriting an existing variable.
  2 个评论
Guillaume
Guillaume 2014-11-26
编辑:Guillaume 2014-11-26
Clément's comment-as-new-answer copied here:
I'm neither going behind the user's back nor trying to second guess what they're doing. What I want to do is requested by the users and is part of the specifications of the tool I'm currently developing. This will be fully documented.
If the users don't provide an output argument, it's their choice, but in that case they expect the constructor to store the result in a variable whose name is generated from the information contained in the input arguments.
The objective here is not to decide whether my idea is ill conceived or not, but to determine whether there is a solution or not.
Guillaume
Guillaume 2014-11-26
编辑:Guillaume 2014-11-26
whether my idea is ill conceived or not: It is. Very much. More on that later.
whether there is a solution or not: on my machine (R2014b), your example works as you want (maybe, probably, see later), so there is no problem in the first place. Which version are you using?
------ the later:
However, even if this behaviour has been requested by the user and it works (for now on r2014b and with this simple class), I would encourage you to pause and rethink the idea. If you're not going round the user back, you're going round matlab's back.
This design is in complete violation of the principles of OOP. A class constructor sole purpose is to construct a single object and return it as its output. Not create a parallel second object. With your design when nargout == 0, two objects are created, one named ans, one named varname. Whether or not, these two are some sort of joined-at-birth twins or not is entirely up to the implementations details of matlab.
Additionally, an object is usually normally considered fully constructed only when the constructor returns. In your case, you're popping an object into existence before the constructor returns, so that evil twin may not even be fully formed.
And who knows how that thing behaves if you then derive from it.
What happens if the class is a handle class? Are both objects ( ans and varname) references to the same object or to two different objects with the same properties? Again, this is all dependent on the internal details of matlab.
Bottom line, in C++ terms, you're in the realm of undefined behaviour. It may work on your test machine, but it may reformat your hard drive, implode the universe, etc. in production. Don't do that!

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Functions 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by