MATLAB Techniques: onCleanup() ‘destructor’

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 a dummy object which you register a function handle that does the cleanup through the constructor argument, and the destructor will blindly call what you’ve registered (the cleanup functor) when its lifecycle ends.

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.


Connection to C++ concept: RAII

This MATLAB technique is an extension of C++’s RAII where you manage the resource exclusively through acquiring resources at constructors and do cleanup at destructors and let the object’s lifecycle managing the timing.

The innovation in onCleanup() is that it saves simple usages (like opening a file or device) from defining a custom class just to take advantage of the destructor:

  • The cleanup class itself is generic and its definition/implementation do not tie to (in other words decoupled from) your application. Your application-specific code is what you’ve registered to an instance of this dummy onCleanup class through the constructor.
  • It’s one line to construct the dummy object with simple cleanup code tucked under an anonymous function (lambda).
  • You can take advantage of a function scope to implicitly delete the cleanup object (thus calling the cleanup operations) or explicitly delete the cleanup object with clear.

GCC and Clang has a __cleanup__ compiler extension (non-standard) attribute that attaches the cleanup function pointer to the variable (resource) to be called when the variable’s lifetime expires. Note that C does not have destructors and the cleanup function is directly attached to the said variable, not a dummy variable that shares the same lifecycle as the resource.

Loading

Subscribe
Notify of
guest
3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
trackback
5 years ago

[…] 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

trackback
5 years ago

[…] 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

trackback
1 year ago

[…] old-fashioned way (not recommended. Use the onCleanup approach instead) to clean up after opening a resource in exception-enabled systems is to use a try […]Report