Matlab onCleanup fatally flawed?

Matlab 2008a provides a new function

onCleanup

Loren Shure writes about it here http://blogs.mathworks.com/loren/

However I think the class is fatally flawed.

As I read the Matlab documentation the implementation of onCleanup is fatally flawed and I don’t think anybody should use it unless some things can be clarified.

According to the Matlab documentation

‘the lifecycle of an object ends *sometime* between the time its variable is no longer used inside the function and the end of the function’

The implementation of onCleanup seems to rely on a subtly different interpretation of object lifecyle.

‘the lifecycle of an object ends at the end of the function within which it’s last reference is lost’

This means the following example

function y = run4
% run4 processes an image file.
[fid,C] = openImageFile4();
blocksize = 100;
y = [];
while something
 dat = fread(fid,count);
 y = doSomething(y,dat);
 something = update(something);
end


is broken.

According to Matlab spec C could be deleted any time after it appears in the line

[fid,C] = openImageFile4();

thus deleting the file handle whilst it was being used. It looks like a classic race condition problem.

To be safe you could rewrite the code

function y = run4
% run4 processes an image file.
[fid,C] = openImageFile4();
blocksize = 100;
y = [];
while something
…dat = fread(fid,count);
…y = doSomething(y,dat);
…something = update(something);
end
C;


But somehow I see the Matlab optimiser at some time in the future stripping out such dead code and rendering the trick useless anyway.

Stylistically it is also not obvious to a reader of the code what C is being used for and it’s inclusion in the code could easily be deleted by an eager maintainer unless the ode is accompanied by copious documentation.

There are however neater ways to solve the same problem in other languages.

The Python way:

http://docs.python.org/whatsnew/pep-343.html


with open(/etc/passwd’, ‘r’) as f:
   for line in f:
      print line


lexical scoping is used to clarify the required lifetime of the file handle f. As well if any exception is thrown from within the block the file is also closed.

The Ruby way:

File.open ‘/etc/passwd’ do |f|
 f.each_line do |l|
   puts l
 end
end


Very similar to the python way and again there is no requirement by the user to provide any cleanup or close functionality. In case of normal block termination or in the event of an error the open function will *always* close the file handle when the block terminates.

The onCleanup functionality could also be dealt with by adding an ensure keyword to the Matlab language as has Ruby and Python.

function do_open(file, flags, action)
 fid = fopen(file, flags)
 try
   action(fid)
 ensure
   fclose(fid)
 end
end


Notice there is no catch above. We don’t want to catch an error we just want to *ensure* that we cleanup if there is an error or not. Any error is propagated to code further upstream to handle. The ensure can be substituted with a catch and rethrow but is a bit uglier as you need to write code to handle closing the file if and if not an error occurs.

Using do_open in Matlab would be like

do_open(/etc/passwd’, ‘r’, @body)
function body(fid)
 read(fid, 10)
 function_with_error()
end


As is obvious the function definition is kind of superfluous and would be nicer with some kind of multi line anonymous function

do_open(/etc/passwd’, ‘r’ ) @(fid)
 read(fid, 10)
 function_with_error()
end





Sponsored by

Sole Central

Your one stop shop for Birkenstock and Crocs shoes and sandles.