How to ensure that onCleanup destroys last
13 views (last 30 days)
Show older comments
I'd like to use onCleanup objects (among other things) to restore the initial matlabpath if the function terminates unexpectedly.
However, there is a problem with this: the execution order of onCleanup is uncertain, and it usually restores path before the destruction of some other created custom objects. As these custom objects depend on the modified path, they can't be properly destroyed with their delete() methods after onCleanup restores the initial path. In fact, onCleanup always seems to execute before the destruction of other objects (may be because it is also created first).
May be it is possible to create one large "restore environment" function, in which the order of destruction could be enforced, like it's advised in the Tips section of the function reference page ).
However, it would be nicer for me just to be able to ensure that onCleanup objects (or better one selected onCleanup object) are destroyed last when function terminates.
0 Comments
Answers (2)
per isakson
on 18 Mar 2023
Edited: per isakson
on 2 Apr 2023
How to avoid this error?
Warning: The following error was caught while executing 'dlnode' class destructor: Method 'delete' is not defined for class 'dlnode' or is removed from MATLAB's search path.
The reason to this error is because the onCleanup object is destroyd before the dlnode object.
"[...] Do not assume that MATLAB destroys one value before another value when the same function contains multiple values."
I assume that onCleanup objects are treated the same way as any other values.
HandleClassDestructor_demo (below) demonstrates one way to "ensure that onCleanup objects are destroyed last when function terminates". However, "(or better one selected onCleanup object)" remains to be solved. The function, whos(*), which is used in the function, mco_names(), "lists in alphabetical order the names". Thus the names of the onCleanup objects may be used to control the order of their destruction. Two more comments: 1) I use evalin(), which I think is legitimate in this case. 2) On my local machine class definitions may reside in packages, but I failed to make that work here.
HandleClassDestructor_demo()
function HandleClassDestructor_demo()
%#ok<*NASGU>
cup = onCleanup( @() fprintf(1,"and finally, destroy the onCleanup object\n") );
str = "abc";
% ...
mhc = [ MyHandleClass(1001), MyHandleClass(1002) ];
pkg = MyHandleClass(1003); % package.MyHandleClass(1003)
% ...
cellfun( @clearvars, mco_names )
end
Addendum: Then there is the requirement, "the function terminates unexpectedly", which isn't met. When I add return on the line before cellfun(@clearvars,mco_names) the demo outputs
and finally, destroy the onCleanup object
MyHandleClass/delete destroys object 1001
MyHandleClass/delete destroys object 1002
MyHandleClass/delete destroys object 1003
Addendum 2023-04-02
The solution above based on the function, mco_names(), is overdoing. The solution below is easier to remember and understand.
function foo
...
[~] = addpath( pth );
cup = onCleanup( @() rmpath( pth ) );
...
clearvars( '-except', 'cup' )
end
0 Comments
See Also
Categories
Find more on Error Handling in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!