{"id":241,"date":"2016-08-10T22:19:29","date_gmt":"2016-08-11T06:19:29","guid":{"rendered":"http:\/\/wonghoi.humgar.com\/blog\/?p=241"},"modified":"2025-03-06T14:04:53","modified_gmt":"2025-03-06T22:04:53","slug":"matlab-techniques-oncleanup-destructor","status":"publish","type":"post","link":"https:\/\/wonghoi.humgar.com\/blog\/2016\/08\/10\/matlab-techniques-oncleanup-destructor\/","title":{"rendered":"MATLAB Techniques: onCleanup() &#8216;destructor&#8217;"},"content":{"rendered":"<p>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\u00a0calls at two places: one at the end of successful execution, the other at the exception handling in try&#8230;catch block:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"matlab\">FID = fopen('a.txt')\ntry\n   \/\/ ... do something here\n   fclose(FID);\ncatch\n   fclose(FID);\nend<\/pre>\n<p>Not only it&#8217;s messy that you have to duplicate your code, it&#8217;s also error prone when you add code in between. If\u00a0your true intention is to close the resource whenever you exit the current program scope, there&#8217;s a better way for you: <a href=\"http:\/\/www.mathworks.com\/help\/matlab\/ref\/oncleanup.html\">onCleanup()<\/a> object. The code above can be simplified as:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"matlab\">FID = fopen('a.txt')\nobj = onCleanup(@() fclose(FID));\n\/\/ ... do something with FID here<\/pre>\n<p>The way <code>onCleanup()<\/code> 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&#8217;ve registered (the cleanup functor) when its lifecycle ends.<\/p>\n<p>Due to copyright reasons, I won&#8217;t copy the simple code here. Just open <code>onCleanup.m<\/code> in MATLAB editor and you&#8217;ll see it that the code (excluding comments) has less words than the description above. Pretty neat!<\/p>\n<p>Normally we use <code>onCleanup()<\/code> 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 &#8216;obj&#8217; to be swept (i.e. its destructors called) when that happens.<\/p>\n<p>Technically, you can make an <code>onCleanup()<\/code> object in the base (root) workspace (aka command window). The destructor will be triggered either when you clear the <code>obj<\/code> explicitly using <code>clear<\/code> or when you exit MATLAB. You can see for yourself with this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"nsis\">obj = onCleanup(@() pause);<\/pre>\n<p>It kind of\u00a0let you do a one-off\u00a0cleanup on exit instead of a recurring cleanup in finish.m.<\/p>\n<p>So the next time you open a resource that needs to be closed whether the program exits unexpectedly or not, use onCleanup()! It&#8217;s one of the elegant,\u00a0smart\u00a0uses of OOP.<\/p>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Connection to C++ concept: RAII<\/h2>\n\n\n\n<p>This MATLAB technique is an extension of C++&#8217;s RAII where you manage the resource exclusively through acquiring resources at constructors and do cleanup at destructors and let the object&#8217;s lifecycle managing the timing.<\/p>\n\n\n\n<p>The innovation in <code>onCleanup()<\/code> is that it saves simple usages (like opening a file or device) from defining a custom class just to take advantage of the destructor: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>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&#8217;ve registered to an <strong>instance<\/strong> of this dummy onCleanup class through the constructor.<br><\/li>\n\n\n\n<li>It&#8217;s <strong>one line<\/strong> to construct the dummy object with simple cleanup code tucked under an anonymous function (lambda).<br><\/li>\n\n\n\n<li>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 <code>clear<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>GCC and Clang has a <code><a href=\"https:\/\/echorand.me\/site\/notes\/articles\/c_cleanup\/cleanup_attribute_c.html\">__cleanup__<\/a><\/code> compiler extension (non-standard) attribute that attaches the cleanup function pointer to the variable (resource) to be called when the variable&#8217;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.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n<div class=\"pvc_clear\"><\/div><p id=\"pvc_stats_241\" class=\"pvc_stats all  \" data-element-id=\"241\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/wonghoi.humgar.com\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p><div class=\"pvc_clear\"><\/div>","protected":false},"excerpt":{"rendered":"<p>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\u00a0calls at two places: one at the end of &hellip; <a href=\"https:\/\/wonghoi.humgar.com\/blog\/2016\/08\/10\/matlab-techniques-oncleanup-destructor\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_241\" class=\"pvc_stats all  \" data-element-id=\"241\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/wonghoi.humgar.com\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[10,6],"tags":[],"class_list":["post-241","post","type-post","status-publish","format-standard","hentry","category-matlab","category-note-to-self"],"_links":{"self":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/241","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/comments?post=241"}],"version-history":[{"count":7,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/241\/revisions"}],"predecessor-version":[{"id":6151,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/241\/revisions\/6151"}],"wp:attachment":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/media?parent=241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/categories?post=241"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/tags?post=241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}