Why does Timer callback experience "too many output arguments" errors?

11 visualizzazioni (ultimi 30 giorni)
I am working on a Matlab Application which has a constantly running timer created in its StartupFcn:
% Build a new timer
app.refreshTimer = timer( ...
'Name', 'MATLAPP_RefreshTimer', ...
'Period', 0.1, ...
'ExecutionMode', 'fixedSpacing', ...
'TasksToExecute', Inf, ...
'TimerFcn', app.refreshTick());
% And start it
start(app.refreshTimer);
The function refreshTick() is actually empty and is a public method in the app.
methods (Access = public)
function refreshTick(app)
% Do nothing
disp(app.FUELPressButton.Value)
return
end
end
When the timer expires, I see the following error:
Error using gith/refreshTick
Too many output arguments.
Error in gith/startupFcn (line 93)
'TimerFcn', app.refreshTick());
Error in gith (line 594)
runStartupFcn(app, @startupFcn)
But the function has no output... why does this happen?
I can sidestep the issue by making the function anonymous:
% Build a new timer
app.refreshTimer = timer( ...
'Name', 'MATLAPP_RefreshTimer', ...
'Period', 0.1, ...
'ExecutionMode', 'fixedSpacing', ...
'TasksToExecute', Inf, ...
'TimerFcn', @(~,~)app.refreshTick());
% And start it
start(app.refreshTimer);
But I do not really understand why that works. I would love a solid technical explanation of what's happening here to cause this, if anyone understands this interaction.

Risposta accettata

Stephen23
Stephen23 il 3 Apr 2022
Modificato: Stephen23 il 3 Apr 2022
"But the function has no output... why does this happen?"
Yes, it does, it has exactly one output argument. On this line:
'TimerFcn', app.refreshTick());
you incorrectly think that you are somehow providing the function as an input argument. But in fact you are calling REFRESHTICK (with no input arguments, but that is not so important here). And when any MATLAB function is called nested inside another function then by definition it is called with exactly one output argument. This is why we can do things like this:
max(rand(5,1))
where RAND is called (just like your function) with exactly one output argument, which is provided as an input to MAX.
The problem is that you called the function.
The solution is to not call the function. You basically have two choices:
  1. use the anonymous function syntax shown in your question, or
  2. provide its function handle like this
'TimerFcn', @app.refreshTick);
and also make sure that the function definition can accept (and ignore) two input arguments:
refreshTick(app,~,~)

Più risposte (1)

Voss
Voss il 3 Apr 2022
Specifying the TimerFcn like this:
'TimerFcn', app.refreshTick(), ...
actually calls the function app.refreshTick, and then tries to set the TimerFcn to the result returned from calling app.refreshTick, but there is no result so you get the error. (Note that the error message says the error happens in startupFcn itself.)
Instead, specify it like this:
'TimerFcn', app.refreshTick, ...
because that refers to the function without calling it. The () on the end calls the function with no inputs.
  2 Commenti
Walter Roberson
Walter Roberson il 3 Apr 2022
'TimerFcn', @app.refreshTick, ...
would refer to the function without calling it.
However the function would be called with two parameters. If the function is defined not to accept any parameters then @(~,~)app.refreshTick() or @(varargin) app.refreshTick() is appropriate
Stephen23
Stephen23 il 3 Apr 2022
Modificato: Stephen23 il 3 Apr 2022
"Instead, specify it like this:'TimerFcn', app.refreshTick, because that refers to the function without calling it."
Are you sure about that (incorrect) statement?
" The () on the end calls the function with no inputs."
And what happens when there are no parentheses...?

Accedi per commentare.

Prodotti


Release

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by