Reputation: 2827
I defined the following class
classdef TimerManager < handle
methods (Access = private)
function obj = TimerManager()
end
end
methods (Static)
function singleObj = getInstance(varargin)
varargin{1}
singleObj = TimerManager();
end
end
methods
function foo(obj)
end
end
end
I found the following code works differently w/ or w/o ; Is this expected? or if I missed anything?
>> TimerManager.getInstance(0).foo()
ans =
0
>> TimerManager.getInstance(0).foo();
Index exceeds matrix dimensions.
Error in TimerManager.getInstance (line 13)
varargin{1}
If I use nargin in side getInstance, it is 0 if I put ; at the end.
Upvotes: 3
Views: 53
Reputation: 65430
Your error has nothing to do with the semi-colon. This has to do with the way that MATLAB handles subscripted referencing of objects (subsref
).
In MATLAB, you cannot "chain" subscripted referencing. For example if we create a cell array, we can't immediately index into this cell array without first assigning it to a temporary variable:
X1 = {'X1', 'X2', 'X3'}{1}
Error: Unbalanced or unexpected parenthesis or bracket.
The same applies for accessing the property or method of an object which is returned by a function. In your case, TimerManager.getInstance
returns an instance which you must first assign to a temporary variable before being able to access it's foo
method.
instance = TimerManager.getInstance(0);
fooResult = instance.foo();
MATLAB makes an attempt to throw an error or warning when it thinks that you're trying to "chain" these subscript references together, but if there is a scenario where an order of subscript operations is valid, then it is unable to throw the appropriate error. You are experiencing one of those cases.
The syntax that you are using is something like the following:
a.b(c).d()
This is valid if a.b
is an array of structs
with a field of d
which is a function handle. In this case, c
is an index.
When MATLAB parses this, it's going to retrieve the value of a.b
, then ensure that c
is a positive integer (a valid index) and is within the bounds of the array a.b
. Then once that's been confirmed, MATLAB will access the d
field and invoke it.
If we go back to your code for a second, we can comment out the varargin{1}
line and get a more useful error message.
TimerManager.getInstance(0).foo();
Subscript indices must either be real positive integers or logicals.
Ok so that kind of makes sense, MATLAB is treating TimerManager.getInstance
as a struct
array and trying to index into it with the 0
which is obviously invalid and results in the error.
With respect to the actual error that you reported, note above that I said that before applying subscript referencing on the supposed struct
array, MATLAB needs to first get the current value of TimerManager.getInstance
. Because MATLAB thinks that this is just a struct
array it's not going to pass any input arguments to it and this is resulting in varargin
being empty and the error that you're seeing.
So your statement is functionally the same as:
instance = TimerManager.getInstance; % No input arguments
instance(0).foo() % Indexing error
Note that this does work if the "input" to getInstance
is 1
since this is a valid index into the 1 x 1
array of TimerManager
instances returned when you call Timermanager.getInstance
with no inputs.
TimerManager.getInstance(1).foo();
Use a temporary variable
instance = TimerManager.getInstance(0);
fooResult = instance.foo();
Or use the method(obj)
notation for invoking the method rather than the obj.method()
notation.
foo(TimerManager.getInstance(0))
None of this is going to be an issue in Octave since it allows "chaining" these subscript references together without the need for a temporary variable.
Upvotes: 3