If your program opens a file, creates a timer(), or whatever resources that needs to be closed when they are no longer needed, before R2008a, you have to put your close resource calls at two places: one at the end of successful execution, the other at the exception handling in try…catch block:
FID = fopen('a.txt') try // ... do something here fclose(FID); catch fclose(FID); end
Not only it’s messy that you have to duplicate your code, it’s also error prone when you add code in between. If your true intention is to close the resource whenever you exit the current program scope, there’s a better way for you: onCleanup() object. The code above can be simplified as:
FID = fopen('a.txt') obj = onCleanup(@() fclose(FID)); // ... do something with FID here
The way onCleanup() works is that it creates an object which you define what its destructor (delete()) does on creation (by the constructor of course) by specifying a function handle. This way when ‘obj’ is cleared (either as it goes out of scope or your explicitly cleared it with ‘clear’), the destructor in ‘obj’ will be activated and do the cleanup actions you specified.
Due to copyright reasons, I won’t copy the simple code here. Just open onCleanup.m in MATLAB editor and you’ll see it that the code (excluding comments) has less words than the description above. Pretty neat!
Normally we use onCleanup() inside a function. The best place to put is is right after you opened a resource because anything in between can go wrong (i.e. might throw exceptions): you want ‘obj’ to be swept (i.e. its destructors called) when that happens.
Technically, you can make an onCleanup() object in the base (root) workspace (aka command window). The destructor will be triggered either when you clear the ‘obj’ explicitly using ‘clear’ or when you exit MATLAB. You can see for yourself with this:
obj = onCleanup(@() pause);
It kind of let you do a one-off cleanup on exit instead of a recurring cleanup in finish.m.
So the next time you open a resource that needs to be closed whether the program exits unexpectedly or not, use onCleanup()! It’s one of the elegant, smart uses of OOP.
2,214 total views, 1 views today
[…] slick idea based on closures to let you sneak your cleanup function (as a function object) into an onCleanup object that will be executed (in destructor) when that object is cleaned up by being out of […]Report
[…] slick idea based on closures to let you sneak your cleanup function (as a function object) into an onCleanup object that will be executed (in destructor) when that object is cleaned up by being out of […]Report