How to ensure that onCleanup destroys last

조회 수: 11 (최근 30일)
Ilya
Ilya 2016년 2월 16일
편집: per isakson 2023년 4월 2일
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.

답변 (2개)

Jacob Lynch August
Jacob Lynch August 2018년 9월 27일

per isakson
per isakson 2023년 3월 18일
편집: per isakson 2023년 4월 2일
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.
The documentation, "Handle Class Destructor", says
"[...] 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()
MyHandleClass/delete destroys object 1001 MyHandleClass/delete destroys object 1002 MyHandleClass/delete destroys object 1003 and finally, destroy the onCleanup object
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

카테고리

Help CenterFile Exchange에서 Software Development Tools에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by