return doesn't work within function

Hi,
I've created a function that should cancel the base script. I call the function with the following code:
if isempty(factor.editingImages.fillHoles) == true
scriptFailed('Failure during selection of fill-threshold.');
end
And this is the function:
function [] = scriptFailed(failureText)
%scriptFailed saves the current workspace and displays a message
% The message can be defined by failureText (string-variable)
filename = [datestr(now,'yyyy-mm-dd,HH.MM.SS'),' canceledWorkspace.mat'];
evalin('base',sprintf('save(''%s'')',fullfile(pwd,filename)))
disp([failureText,' The programm canceled and saved the workspace ("',filename,'").'])
close all
return
end
But after calling the function (workspace is always created as it should be, so the function is always active), the next lines after the if-loop are trying to do something but can't, because there are some variables missing. Why does return doesn't cancel the running script?
Thanks for your help!

 采纳的回答

Matt J
Matt J 2020-11-10
编辑:Matt J 2020-11-10
You cannot give a function the power to abort another function. See also,
Your code should look like this, instead:
if isempty(factor.editingImages.fillHoles) == true
scriptFailed('Failure during selection of fill-threshold.');
return
end
function [] = scriptFailed(failureText)
%scriptFailed saves the current workspace and displays a message
% The message can be defined by failureText (string-variable)
filename = [datestr(now,'yyyy-mm-dd,HH.MM.SS'),' canceledWorkspace.mat'];
evalin('base',sprintf('save(''%s'')',fullfile(pwd,filename)))
disp([failureText,' The programm canceled and saved the workspace ("',filename,'").'])
close all
end

6 个评论

I think I don't fully understand, because return is after calling evalin and I thought evailn is executed and finished, so that any other command could be called.
Matt J
Matt J 2020-11-10
编辑:Matt J 2020-11-10
The return command that you issue inside scriptFailed() is doing what it should: it is causing scriptFailed() to terminate and return control to whatever function has called scriptFailed(). The return command has no effect and can have no effect outside the workspace of scriptFailed().
Ultimately, of course, you accomplishes nothing useful by putting return at the end of a function. Putting a return at the last line of a function cannot accomplish anything, because the function was about to terminate anyway.
And the variables being returned probably would still be undefined.
You should probably error()
Thank you! Now I think I didn't fully understand the return function. I just can't believe that there is no such function to stop executing the current script or "level of functions" without using quit() or exit but it seems to be like that (or some other workaround like in your link).
No, see my edited answer. You can abort the current script as long as you call return in the workspace of that script.
I put it at the end of the function because I thought it would also stop execution the script above. I have several conditions that are calling this function and should stop the whole script. Then I could've let return within the function. Now I'm taking your variant and put it everywhere right after calling the function.
Thank you for your help!

请先登录,再进行评论。

更多回答(1 个)

Steven Lord
Steven Lord 2020-11-10
Why does return doesn't cancel the running script?
It does exit from the currently running function. It exits the scriptFailed function, returning control to the script or function that called scriptFailed.
To do what you want, either:
  1. move the return keyword from inside scriptFailed to just after scriptFailed is called in its caller. Note that if scriptFailed itself was called from a function, it will return back to control of its caller.
  2. Have scriptFailed throw an error indicating the problem. Unless something higher up in the caller stack is running this code in the try section of a try / catch block the error will work its way up through the caller stack and eventually cause the top-level script or function to exit. Even if something higher in the caller stack does try / catch the error, it can rethrow the error once it has performed whatever cleanup or error handling it needs to perform.

3 个评论

Thank you for your solutions! I think I will go with the first one.
While I wrote them in that order because I thought of them in that order, in the situation you described I'd prefer the second. Something fatal to the execution of your program occurred, something from which it cannot recover. Having the code throw an error will indicate that the code was unsuccessful in a way that's harder for your user to ignore than a simple displayed message. The red text in the Command Window tends to stand out. Compare:
if 1+1 ~= 3
disp('Incorrect answer')
end
Incorrect answer
versus
if 1+1 ~= 3
error('Incorrect answer')
end
Incorrect answer
Which catches your eye more quickly?
If you are using functions and you need to go back up through multiple levels without the function returning its usual value, then you should be using error() . error() can head back up the call stack until it encounters a catch block, and it does not require that each function along the way return anything at all.

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Startup and Shutdown 的更多信息

产品

版本

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by